symfonyswaggernelmioapidocbundle

How annotations works on NelmioApiDocBundle


On my symfony project, I followed the documentation of the NelmioApiDocBundle to document my api. I can access to my endpoints on http://localhost/api/doc and I added a custom endpoint to test http://localhost/healthcheck who return a Json 200 response. My problem is when I try to add annotations and informations about the endpoint, it doesn't work. Nothing is displayed on the documentation, does I miss something ?

Here is my nelmio_api_doc.yaml

    documentation:
        info:
            title: My App
            description: This is an awesome app!
            version: 1.0.0
    areas: # to filter documented areas
        path_patterns:
            - ^/api(?!/doc$) # Accepts routes under /api except /api/doc
            - ^/healthcheck # Accepts routes under /api except /api/doc

Here is my controller

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;
use Nelmio\ApiDocBundle\Annotation\Model;
use Nelmio\ApiDocBundle\Annotation\Security;
use OpenApi\Annotations as OA;

class HealthcheckController extends AbstractController
{
    #[Route('/healthcheck', name: 'healthcheck', methods: 'GET')]
    /**
     * 
     * @OA\Get(
     *     path="/healthcheck",
     *     summary="Check the health of the application",
     *     description="This endpoint is used to check the health of the application.",
     *     @OA\Response(
     *         response=200,
     *         description="Returns OK if the application is healthy",
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="result", type="string", example="OK")
     *         )
     *     ),
     *     security={}
     * )
     * 
     */
    public function index(): JsonResponse
    {
        return new JsonResponse(["result" => "OK"], 200);
    }
}

Rendered of the documentation without infos


Solution

  • This is my code for the health controller of a symfony 6 application. And yes getting the attributes right is tiresome until you get practise:

    <?php
    
    declare(strict_types=1);
    
    namespace App\Controller;
    
    use App\Api\Dto\InfoDto;
    use Nelmio\ApiDocBundle\Annotation\Model;
    use OpenApi\Attributes as OA;
    use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
    use Symfony\Component\HttpFoundation\JsonResponse;
    use Symfony\Component\HttpFoundation\Response;
    use Symfony\Component\Routing\Annotation\Route;
    
    class HealthController extends AbstractController
    {
        #[
            OA\Get(
                operationId: 'Readiness',
                description: 'Readiness',
                summary: 'checks readiness of application',
                tags: ['health readiness'],
                responses: [
                    new OA\Response(
                        response: 200,
                        description: 'Success',
                        content: new OA\JsonContent(ref: new Model(type: InfoDto::class), type: 'object')
                    ),
                    new OA\Response(response: 500, description: 'Internal Server Error'),
                ]
            ),
            Route(path: '/health/readiness', name: 'readiness', methods: ['GET'])
        ]
        public function readiness(): JsonResponse
        {
            return new JsonResponse(null, Response::HTTP_NO_CONTENT);
        }
    
        #[
            OA\Get(
                operationId: 'health',
                description: 'health',
                summary: 'checks health of application',
                tags: ['health'],
                responses: [
                    new OA\Response(
                        response: 200,
                        description: 'Success',
                        content: new OA\JsonContent(ref: new Model(type: InfoDto::class), type: 'object')
                    ),
                    new OA\Response(response: 500, description: 'Internal Server Error'),
                ]
            ),
            Route(path: '/health', name: 'health', methods: ['GET'])
        ]
        public function health(): JsonResponse
        {
            return new JsonResponse(null, Response::HTTP_NO_CONTENT);
        }
    }