openapiswagger-phpnelmioapidocbundle

NelmioApiDocBundle v4.0.0-BETA1, $ref not found


I have a DTO like this:

# AppBundle\DTO

/**
 * @OA\Schema(
 *      schema="ProductDto",
 *      type="object",
 *      required={
 *          "foo",
 *          "bar",
 *          "baz",
 *      },
 * )
 */
class ProductDto
{
    /**
     * @OA\Property(description="foo bar baz")
     * @var string|null
     */
    private $foo;

    ...
 }

I am trying to reference this DTO in my controller, but it seems that this is file is not being parsed.

# AppBundle\Controller\Api\v1
class ProductController {

  ...

  /**
    * @OA\Post(
    *      @OA\RequestBody(
    *          required=true,
    *          content={
    *              @OA\MediaType(
    *                  mediaType="application/json",
    *                  @OA\Schema(
    *                      type="object",
    *                      ref="#/components/schemas/ProductDto",
    *                  ),
    *              ),
    *          }
    *      ),
    * )
    */
  public function create(Request $request): ApiResponse

  ...
}

This results in:

User Notice: $ref "#/components/schemas/ProductDto" not found for @OA\Schema() in \Doctrine\Common\Annotations\DocParser->Annotation() in /srv/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php on line 827

It seems if I put my DTO into the Controller namespace, the file is being found and parsed, but the referencing still does not work. It works with the pure swagger-php package though.

I am using the current Beta (v4.0.0, NelmioApiDocBundle), since I want to use OpenAPI 3. Do I need to reference it differently? Is that a bug in the package, or am I doing it wrong?


Solution

  • NelmioApiDocBundle uses zircote/swagger-php annotations but it doesn't parse them the same way zircote/swagger-php does.

    The idea is to leverage metadata already provided by symfony to simplify writing documentations. Among those metadata are the path of your routes, validation annotations, fosrest annotations and the properties of your models exposed to the Symfony serializer (or to the JMS serializer depending on what you use).

    In order to do that, this bundle does not load all the swagger-php annotations it find and instead does some specific loading, it loads @Operation annotations on controller actions (and does not require a path) for instance. The same applies to models, they need to be referenced somewhere using the special annotation @Model in order to add some context to their loading.

    You can find some more context in the documentation of the bundle: https://symfony.com/doc/current/bundles/NelmioApiDocBundle/index.html#use-models.

    In your case, you should use ref=@Nelmio\ApiDocBundle\Annotation\Model(type=ProductDTO::class instead of ref="#/components/schemas/ProductDto.