swagger-php icon indicating copy to clipboard operation
swagger-php copied to clipboard

Suppress the generation of operationId in the contract

Open jfiala opened this issue 1 year ago • 4 comments

Is it possible to suppress the generation of the operationId?

Currently the operationId is generated with a hash value if the attribute operationId is missing for an operation.

This causes strange behaviour with the OpenAPI-Generator for language java. Besides that this needs to be fixed at the OpenAPI-Generator, is it possible to omit the operationId easily?

There is an issue with this topic, but it has no clear instructions how to omit the operationId: https://github.com/zircote/swagger-php/issues/930 Some improvements to operationId were added here: https://github.com/zircote/swagger-php/pull/942

Trying to instantiate the Generator manually is not allowed:

$generator = (new Generator())->updateProcessor(new OperationId(false));
$openapi = $generator::scan(['api']);
Fatal error: Uncaught Error: The "Generator" class is reserved for internal use and cannot be manually instantiated in C:\xxx\api-docs.php:25 Stack trace: #0 {main} thrown in C:\xxx\api-docs.php on line 25

So how can the operationId be omitted generally?

jfiala avatar Apr 05 '24 19:04 jfiala

This can currently be solved by overriding the operationId in the OpenApi\Processors\OperationId.php:

 public function __invoke(Analysis $analysis)
    {
...
if ($operationId) {
                    $operationId = strtoupper($operation->method) . '::' . $operation->path . '::' . $operationId;
                    $operation->operationId = $this->hash ? md5($operationId) : $operationId;
                 
// RESET operationId: alway override the operationId to UNDEFINED   
                    $operation->operationId = Generator::UNDEFINED;
                }

Not a clean solution, but for now it works...

jfiala avatar Apr 05 '24 19:04 jfiala

Depends on how you are using swagger-php. Programmatically you always have the option to remove a processor from the pipeline.

$generator = new Generator();
// ....
$generator->removeProcessor($processor);

Only downside right now is that processors are compared using ===, so you'd have to find the actually registered instance, for example:

        $processors = $generator->getProcessors();

        $operationIdProcessor = null;
        foreach ($processors as $processor) {
            if ($processor instanceof OperationId) {
                $operationIdProcessor = $processor;
                break;
            }
        }
        $generator->removeProcessor($operationIdProcessor);

DerManoMann avatar Apr 14 '24 02:04 DerManoMann

I just tried that, the OperationId-Processor is actually removed from the processors. However, it still is invoked during the scan process:

$generator = new \OpenApi\Generator;

$processors = $generator->getProcessors();

$operationIdProcessor = null;
foreach ($processors as $processor) {
    if ($processor instanceof OperationId) {
        echo "*** Found OperationId-Processor";
        $operationIdProcessor = $processor;
        break;
    }
}

// OperationId-Process is here:
var_dump($generator->getProcessors());

var_dump($operationIdProcessor);
$generator->removeProcessor($operationIdProcessor);

// OperationId-Process is removed:
var_dump($generator->getProcessors());

$openapi = $generator::scan(...);

// OperationId-Processor invoke is still called!

jfiala avatar Apr 15 '24 09:04 jfiala

The scan() method is static, so it doesn't really know about the changed processors in $generator. It should really be deprecated; in this case you really want to call $generator->generate().

If you insist on using scan() then that should look something like this:

    Generator::scan($sources, ['processors' => $generator->getProcessors());

scan is the static, untyped version of generate(). You can set all options it accepts using fluid methods on $generator:

    public static function scan(iterable $sources, array $options = []): ?OA\OpenApi
    {
        // merge with defaults
        $config = $options + [
                'aliases' => self::DEFAULT_ALIASES,
                'namespaces' => self::DEFAULT_NAMESPACES,
                'analyser' => null,
                'analysis' => null,
                'processors' => null,
                'logger' => null,
                'validate' => true,
                'version' => null,
            ];

        return (new Generator($config['logger']))
            ->setVersion($config['version'])
            ->setAliases($config['aliases'])
            ->setNamespaces($config['namespaces'])
            ->setAnalyser($config['analyser'])
            ->setProcessors($config['processors'])
            ->generate($sources, $config['analysis'], $config['validate']);
    }

DerManoMann avatar Apr 17 '24 04:04 DerManoMann