nelmio / NelmioApiDocBundle

Generates documentation for your REST API from annotations
MIT License
2.23k stars 836 forks source link

Favor OpenAPI Annotations Over FOSRestBundle Annotations #1775

Open jlekowski opened 3 years ago

jlekowski commented 3 years ago

With both FosRestBundle and ApiDocBundle annotations, I get the following warning:

User Warning: Multiple @OA\MediaType() with the same mediaType="application/json":
\Nelmio\ApiDocBundle\RouteDescriber\FosRestDescriber->getContentSchemaForType() in /home/jerzy/dev/temp/symfony-temp/vendor/nelmio/api-doc-bundle/RouteDescriber/FosRestDescriber.php on line 133

The warning is triggered from https://github.com/zircote/swagger-php/blob/3.1.0/src/Annotations/AbstractAnnotation.php#L407 when requesting nelmio_api_doc.controller.swagger or nelmio_api_doc.controller.swagger_ui (in my case I accessed /api/doc.json URL).

The reason for that is that both PhpDocDescriber and FosRestDescriber add application/json media type to request body. One adds using numeric key here https://github.com/zircote/swagger-php/blob/3.1.0/src/Annotations/AbstractAnnotation.php#L176. Another one using media type (e.g. application/json) as a key https://github.com/nelmio/NelmioApiDocBundle/blob/master/RouteDescriber/FosRestDescriber.php#L131. So we end up having both and the warning. My workaround is to add a normalizer that removes media type added by FosRestDescriber if also one added by PhpDocDescriber is present https://gist.github.com/jlekowski/c2c959426bec31aa6ec4187537339f81. I want PhpDocDescriber to take precedence

An example controller:

<?php

namespace App\Controller;

use FOS\RestBundle\Controller\AbstractFOSRestController;
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Request\ParamFetcherInterface;
use Nelmio\ApiDocBundle\Annotation\Operation;
use OpenApi\Annotations as OA;
use Symfony\Component\Routing\Annotation\Route;

class TestController extends AbstractFOSRestController
{
    /**
     * @Operation(
     *     @OA\RequestBody(
     *         @OA\MediaType(
     *             mediaType="application/json",
     *             @OA\Schema(
     *                 @OA\Property(
     *                     property="id",
     *                     type="integer"
     *                 )
     *             )
     *         )
     *     )
     * )
     * @Rest\RequestParam(name="price", requirements="\d+", allowBlank=false)
     *
     * @Route("/test", methods={"POST"})
     */
    public function testAction(ParamFetcherInterface $paramFetcher)
    {
    }
}
jlekowski commented 3 years ago

In general FOSRestBundle annotations seem to overwrite Swagger-Php annotations (I believe it should be the other way around). For example for query parameters default, pattern, and format are taken from FOSRestBundle annotations https://github.com/nelmio/NelmioApiDocBundle/blob/master/RouteDescriber/FosRestDescriber.php#L150

thgross commented 3 years ago

I have the same problem in my project. Thank you for your workaround, it works for me now!

This should be addressed though, because using both FOSRestBundle and NelmiApiDocBundle is a logical thing to do ...

chrisguitarguy commented 2 years ago

Adjusted the title to be (hopefully) more descriptive of the desired change here.

Heaven31415 commented 1 year ago

Thank you for the workaround. It was quite useful for me. I had identical problem while using FOSRestBundle and NelmioApiDocBundle.

Is there any progress with the issue?