Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Api Doc Bundle Laravel Package

oro/api-doc-bundle

Fork of NelmioApiDocBundle 2.x updated for Symfony 5 compatibility. Generates API documentation with a Swagger-UI-inspired interface, including routes, parameters, and responses, with PHPUnit tests and MIT license.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps for Laravel Integration

  1. Install Dependencies: Since this is a Symfony bundle, install it alongside Symfony components for compatibility:

    composer require oro/api-doc-bundle symfony/serializer symfony/http-kernel
    
  2. Configure Laravel to Use Symfony Components: Add Symfony’s HttpKernel and Serializer to Laravel’s service provider:

    // config/app.php
    'providers' => [
        // ...
        Symfony\Component\HttpKernel\HttpKernelBundle\HttpKernelBundle::class,
        Symfony\Component\Serializer\SerializerBundle\SerializerBundle::class,
    ],
    
  3. Basic Bundle Setup: Create a custom service provider to bridge Symfony and Laravel:

    php artisan make:provider NelmioApiDocServiceProvider
    

    Register the bundle in register():

    use Oro\ApiDocBundle\NelmioApiDocBundle;
    use Symfony\Component\HttpKernel\Kernel;
    
    public function register()
    {
        if (!class_exists(Kernel::class)) {
            $this->app->register(Symfony\Component\HttpKernel\HttpKernelBundle\HttpKernelBundle::class);
        }
        $this->app->register(NelmioApiDocBundle::class);
    }
    
  4. First Use Case: Annotate a Laravel controller to generate API docs:

    use Nelmio\ApiDocBundle\Annotation\ApiDoc;
    use Nelmio\ApiDocBundle\Annotation\Model;
    use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
    
    class UserController extends Controller
    {
        /**
         * @Route("/users/{id}", name="get_user", methods={"GET"})
         * @ApiDoc(
         *     description="Get a user by ID",
         *     resource=true,
         *     requirements={
         *         {"name"="id", "dataType"="integer", "requirement"="\d+"}
         *     },
         *     statusCodes={
         *         200={"description"="User found"},
         *         404={"description"="User not found"}
         *     }
         * )
         * @Model(type="App\Entity\User", groups={"user_read"})
         */
        public function getUser(int $id)
        {
            return User::findOrFail($id);
        }
    }
    
  5. Access Documentation: Add a route to serve the NelmioApiDocBundle UI:

    Route::get('/api/doc', [NelmioApiDocBundle::class, 'indexAction']);
    

    Visit /api/doc to see the interactive API documentation.


Implementation Patterns

Workflows

  1. Annotation-Driven Documentation:

    • Use @ApiDoc, @Route, and @Model annotations to document controllers, routes, and entities.
    • Example for a POST endpoint:
      /**
       * @Route("/users", name="create_user", methods={"POST"})
       * @ApiDoc(
       *     description="Create a new user",
       *     input="App\\Dto\\CreateUserDto",
       *     statusCodes={
       *         201={"description"="User created"},
       *         400={"description"="Invalid input"}
       *     }
       * )
       */
      public function createUser(Request $request)
      {
          // ...
      }
      
  2. Entity Documentation:

    • Use @Model to document entity fields and groups:
      /**
       * @Model(
       *     type="App\Entity\User",
       *     groups={"user_read", "user_write"}
       * )
       */
      class User {}
      
  3. Security Schemes:

    • Define API keys or OAuth2 in nelmio_api_doc.yaml:
      nelmio_api_doc:
          documentation:
              securityDefinitions:
                  api_key:
                      type: "apiKey"
                      in: "header"
                      name: "X-API-KEY"
      
  4. Customizing the UI:

    • Override the Swagger UI template by copying vendor/nelmio/api-doc-bundle/Resources/views/SwaggerBundle/index.html.twig to resources/views/vendor/nelmio_api_doc/index.html.twig.

Integration Tips

  1. Laravel Route Integration:

    • Use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route annotations alongside Laravel’s Route attributes:
      use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
      use Symfony\Component\Routing\Annotation\Route as SymfonyRoute;
      
      /**
       * @SymfonyRoute("/users/{id}", name="get_user")
       * @Route(name: "get_user", path: "/users/{id}", methods: ["GET"])
       */
      
  2. Symfony Serializer for Request/Response:

    • Configure Symfony’s Serializer to handle Laravel’s data structures:
      $serializer = Serializer::create([
          new XmlSerializer(),
          new JsonSerializer(),
          new ObjectNormalizer(),
      ], [new DateTimeNormalizer()]);
      
  3. Caching Generated Docs:

    • Cache the generated OpenAPI schema to avoid reprocessing annotations:
      $cache = new FileCache(sys_get_temp_dir());
      $generator = new OpenApiGenerator($cache);
      
  4. Validation:

    • Use the generated OpenAPI schema to validate requests/responses with tools like zircote/swagger-php.
  5. Testing:

    • Write PHPUnit tests to verify annotations and generated docs:
      public function testApiDocAnnotations()
      {
          $reflection = new \ReflectionClass(UserController::class);
          $annotations = $reflection->getMethod('getUser')->getAnnotations();
          $this->assertArrayHasKey('ApiDoc', $annotations);
      }
      

Gotchas and Tips

Pitfalls

  1. Symfony-Specific Dependencies:

    • Issue: The bundle relies on Symfony’s HttpKernel, EventDispatcher, and Serializer.
    • Fix: Mock or replace these with Laravel equivalents. For example, use spatie/laravel-annotation-reader instead of SensioFrameworkExtraBundle.
  2. Annotation Parsing Conflicts:

    • Issue: Laravel’s doctrine/annotations may not fully support Symfony’s annotation format.
    • Fix: Ensure you’re using the latest doctrine/annotations and configure it to read PHPDoc comments:
      $annotationReader = new \Doctrine\Common\Annotations\AnnotationReader();
      $annotationReader->addNamespace('Nelmio\ApiDocBundle\Annotation');
      
  3. Route Collection Mismatch:

    • Issue: The bundle expects Symfony’s RouteCollection, but Laravel uses its own router.
    • Fix: Convert Laravel routes to a Symfony-compatible format:
      $routeCollection = new RouteCollection();
      foreach (Route::getRoutes() as $route) {
          $symfonyRoute = new Route(
              $route->uri(),
              new RequestContext(),
              new RouteCollection()
          );
          $routeCollection->add($route->getName(), $symfonyRoute);
      }
      
  4. Circular Dependencies:

    • Issue: Mixing Laravel’s service container with Symfony’s DI can cause conflicts.
    • Fix: Use a single container (e.g., Laravel’s) and manually register Symfony services:
      $this->app->singleton(Symfony\Component\Serializer\SerializerInterface::class, function () {
          return Serializer::create([/* ... */]);
      });
      
  5. Deprecated Annotations:

    • Issue: Some annotations (e.g., @ApiResource) may be deprecated in newer versions.
    • Fix: Check the NelmioApiDocBundle documentation for updates and use alternatives like @ApiDoc.
  6. Performance with Large APIs:

    • Issue: Generating docs for thousands of routes can be slow.
    • Fix: Cache the generated OpenAPI schema and use lazy-loading for route annotations.

Debugging Tips

  1. Enable Debug Mode:

    • Set nelmio_api_doc.debug: true in nelmio_api_doc.yaml to see detailed errors.
  2. Check Generated Schema:

    • Access /api/doc.json to inspect the raw OpenAPI schema for errors.
  3. Validate Annotations:

    • Use phpdoc/parser to validate annotations before runtime:
      $parser = new \phpDocumentor\Reflection\DocBlockFactory();
      $docBlock = $parser->create($reflectionMethod);
      
  4. Symfony Event Listeners:

    • If using Symfony events (e.g., kernel.request), ensure they’re properly bound to Laravel’s event system:
      Event::listen('kernel.request', function ($request) {
          // Adapt Symfony event logic here
      });
      

Extension Points

  1. Custom Annotation Handlers:
    • Extend the annotation parser to support custom annotations:
      class CustomAnnotationHandler extends AbstractAnnotationHandler
      {
          public function getAnnotationName()
          {
              return 'CustomAnnotation';
          }
      
          public function handle(Annotation $annotation, Controller
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity