Search code examples
doctrine-ormentitymanagerapi-platform.comdoctrine-mapping

Api-Platform + Swagger: group operations/entities by Doctrine or ApiPlatform mapping


I have config/packages/api_platform.yaml:

api_platform:
    mapping:
        paths: 
            - '%kernel.project_dir%/src/Entity'
            - '%kernel.project_dir%/old/Entity'

In both namespaces I have entities with the same name. What do I have to do for them to display in /docs grouped into different mappings and not by entity class name alone.

How do I configure prefix "globally" for each of the namespaces?


Solution

  • API Platform does not provide this configuration right now you will have to decorate the OpenApiFactory like this

    The swagger documentation groups them by their tags

    <?php
    // src/OpenApi/OpenApiFactory.php
    
    namespace App\OpenApi;
    
    use ApiPlatform\Core\OpenApi\Factory\OpenApiFactoryInterface;
    use ApiPlatform\Core\OpenApi\OpenApi;
    use ApiPlatform\Core\OpenApi\Model;
    
    final class OpenApiFactory implements OpenApiFactoryInterface
    {
        private $decorated;
    
        public function __construct(OpenApiFactoryInterface $decorated)
        {
            $this->decorated = $decorated;
        }
    
        public function __invoke(array $context = []): OpenApi
        {
            $openApi = $this->decorated->__invoke($context);
    
            $paths = $openApi->getPaths()->getPaths();
    
            $filteredPaths = new Model\Paths();
            foreach ($paths as $path => $pathItem) {
                // Here you can check the tags for each Operations
                // Add custom logic with the snippet below
            }
    
            return $openApi->withPaths($filteredPaths);
        }
    }
    

    Here come the dirty part, tags will be EntityName and not full namespace name I would make a list of all old entity, filter the current tag on it and change to old or new (Below is pseudo-code)

    $OldEntityList = ['entity1', 'entity2', ...]
    foreach ($Operations as $op) {
      if (in_array($op->getTags(), $OldEntityList) {
         $op->withTags('old');
      } else {
         $op->withTags('new');
      }
    }