nelmio / NelmioApiDocBundle

Generates documentation for your REST API from annotations
MIT License
2.22k stars 832 forks source link

Multiple Definitions for @OA\Get->path Warning leads to Symfony ErrorException #1858

Open c-schinzer opened 3 years ago

c-schinzer commented 3 years ago

I do observe several issues when running Nelmio API Doc along with FOS Rest Bundle in the context of Symfony 4.4; when switching to http://mysite/api/doc I get a Symfon ErrorException as follows:

User Warning: Multiple definitions for @OA\Get()->path
Using: \Nelmio\ApiDocBundle\ApiDocGenerator->generate() in /tsl/app/PDB_STG_Apache_1/htdocs/vendor/nelmio/api-doc-bundle/ApiDocGenerator.php on line 82
Skipping: \DnsEndpointsController->getDnsEndpointsAction() in /tsl/app/PDB_STG_Apache_1/htdocs/src/RestController/DnsEndpointsController.php on line 82

Current versions:

Now this message for me has several issues:

  1. Why does Symfony render a blocking ErrorException from a User Warning? I would have expected Warning Level, but still a rendering of the doc page.

  2. In my code the row referenced in the Warning message and mentioned to be Skipped looks like this:

    ...
    80:     *     @OA\Parameter(
    81:     *         name="managedByUnit", in="query", required=false,
    >> 82:     *         description="Managed by Unit on the Subject",
    83:     *         @OA\Schema(type="string")
    84:     *     ),
    85:     *     @OA\Parameter(
    86:     *         name="name", in="query", required=false,
    ...

    Hence nothing particular to be skipped I would say in the middle of a Parameter definition. Is the referenced line 82 correct? Is it possibly just the same line as referenced in the previous 'Using:' message? That would represent a tiny but relevant bug as it does not give the expected guidance to the programmer on what will be skipped.

  3. The Warning as such for me is unclear and possibly a bug as this very file declares the following two methods:

    ...
    20: use FOS\RestBundle\Controller\Annotations as Rest;
    21: use FOS\RestBundle\Request\ParamFetcherInterface;
    22: use Nelmio\ApiDocBundle\Annotation\Model;
    23: use OpenApi\Annotations as OA;
    ...
    49:     *
    50:     * @Rest\Route("/subjects/dnsendpoints", name="rest_api_subjects_get_dns_endpoints", methods={"GET"})
    51:     *
    52:     * @OA\Get(
    53:     *     path="/subjects/dnsendpoints",
    54:     *     operationId="rest_api_subjects_get_dns_endpoints",
    55:     *     tags={"Subjects - DnsEndpoints"},
    56:     *     summary="Get all DNS Endpoint entities listed in the database",
    ...
    142:     * @throws \LogicException
    143:     */
    144:    public function getDnsEndpointsAction(ParamFetcherInterface $paramFetcher): Response
    145:    {
    ...
    205:     *
    206:     * @Rest\Route("/subjects/dnsendpoints/{instanceId}", name="rest_api_subjects_get_dns_endpoint_details", methods={"GET"})
    207:     *
    208:     * @OA\Get(
    209:     *     path="/subjects/dnsendpoints/{instanceId}",
    210:     *     operationId="rest_api_subjects_get_dns_endpoint_details",
    211:     *     tags={"Subjects - DnsEndpoints"},
    212:     *     summary="Get a DNS Endpoint entity by InstanceId",
    ...
    230:     * @throws \LogicException
    231:     */
    232:    public function getSingleDnsEndpointAction(string $instanceId): Response
    233:    {
    ...

    So there are two GET methods, with similar but not equal paths. I checked the codebase and there is no other place where routes for /subjects/dnsendpoints are used or declared. I am uncertain about the overlap and thus potential concurrence betweem the @Rest and the @OA annotations, though.

Can anyone shed some light into this? Any hint is gratefully appreciated :)

Carsten

c-schinzer commented 3 years ago

Hint: Use ./bin/console nelmio:apidoc:dump in your local environment to debug your annotated RestControllers in your dev environment. Kudos to the Nelmio devs for that feature. It saves a ton of time and I got aware only when digging deep here.

It appears the issue is with the double definition of the path through @Rest\Route() annotation and the separate path= statement on the @OA\Get() annotation. Skipping the extra statement for path removes the error for this file.

GuilhemN commented 3 years ago

This is actually quite odd and should not be happening. But it may just be that you're using an outdated version of NelmioApiDocBundle, could you try upgrading to the latest version of NelmioApiDocBundle v4?