API 平台 - 自定义控制器/动作描述注释不起作用

API Platform - Custom controller / action description annotations not working

如果我在这里遗漏了什么,真的很抱歉,但我已经搜索了各种问题和文档,但我找不到为什么这不起作用。也许我需要另一个关于使用互联网的教程 ;)

考虑下面的实体注释,在 openapi_context 部分中 body.descriptionresponses.200.description 根本没有效果,这让我有点生气......你应该知道我正在使用 de/normalization 上下文,但这似乎不相关,所以我将其排除在外。


/**
 * User entity
 *
 * @API\ApiResource(
 *  collectionOperations={
 *      "authenticate"={
 *          "method"="POST",
 *          "status"=200,
 *          "path"="/authenticate",
 *          "controller"=UserLoginController::class,
 *          "openapi_context"={
 *              "responses"={"200"={"description"="API token and secret"}},
 *              "body"={"description"="Login details"},
 *              "summary"="User authentication",
 *              "description"="Provides auth tokens on success",
 *          },
 *      },
 *  }
 * )
 *
 */
class User implements UserInterface
{
    ...
}

结果(蓝色方块符合预期,红色方块无效):

我在这个问题上花了太多时间,如果有人能帮助我解决这个问题,我将不胜感激。我有 checked/tried 以下无济于事;

Composer 版本(相关部分):

{
    "require": {
        "php": ">=7.2.5",
        "api-platform/core": "^2.6",
        "symfony/framework-bundle": "5.2.*"
    }
}

经过一些试验,我发现 openapi_context 注释属性似乎确实忽略了响应文档。但是,它确实允许您提供缺少的请求正文描述:

#[ApiResource(
    collectionOperations: [
        'test' => [
            'method' => 'POST',
            'path' => '/test',
            'openapi_context' => [
                'summary' => 'The endpoint summary',
                'description' => 'The endpoint description',
                'requestBody' => [
                    'description' => 'The endpoint request body description', // This one
                    'content' => [
                        'application/json' => [
                            'schema' => [
                                '$ref' => '#/components/schemas/MyResource-some.group'
                            ],
                        ],
                    ],
                ],
            ],
        ]
    ],
)]

我正在使用 PHP 8.0.3 和 API 平台 2.6.3 写这篇文章时,将注释更改为 docblocks 应该会产生相同的结果不过你的结果。

然而,为了记录端点响应规范,我不得不实现自定义 OpenApiFactoryInterface:

<?php declare(strict_types = 1);

namespace App;

use ApiPlatform\Core\OpenApi\Factory\OpenApiFactoryInterface;
use ApiPlatform\Core\OpenApi\Model\Operation;
use ApiPlatform\Core\OpenApi\Model\PathItem;
use ApiPlatform\Core\OpenApi\Model\RequestBody;
use ApiPlatform\Core\OpenApi\OpenApi;
use ArrayObject;
use UnexpectedValueException;

class MyResourceOpenApiFactory implements OpenApiFactoryInterface
{
    private OpenApiFactoryInterface $openApiFactory;

    public function __construct(OpenApiFactoryInterface $openApiFactory)
    {
        $this->openApiFactory = $openApiFactory;
    }

    public function __invoke(array $context = []): OpenApi
    {
        $openApi = ($this->openApiFactory)($context);
        $components = $openApi->getComponents();
        $schemas = $components->getSchemas();
        if (null === $schemas) {
            throw new UnexpectedValueException('Failed to obtain OpenApi schemas');
        }

        $pathItem = new PathItem(
            'MyResource test endpoint',
            'A test summary',
            'A test description',
            null,
            null,
            // Your custom post operation
            new Operation(
                'testMyResourceCollection', // the operation route name
                [
                    'MyResource' // your resource name
                ],
                [
                    // response specifications
                    '201' => [
                        'description' => 'test endpoint 201 response description',
                        'content' => [
                            'application/json' => [
                                'schema' => [
                                    '$ref' => '#/components/schemas/MyResource-read', // your resource (read) schema
                                ],
                            ],
                        ],
                    ],
                ],
                'A test endpoint summary',
                'A test endpoint description',
                null,
                [],
                new RequestBody(
                    'A test request body description',
                    new ArrayObject([
                        'application/json' => [
                            'schema' => [
                                '$ref' => '#/components/schemas/MyResource-write', // your resource (write) schema
                            ],
                        ],
                    ]),
                ),
            ),
        );

        $paths = $openApi->getPaths();
        $paths->addPath('/my_resources/test', $pathItem);
        return $openApi;
    }
}

将此 OpenApiFactoryInterface 实现作为装饰器由服务容器连接到 api_platform.openapi.factory:

App\MyResourceOpenApiFactory:
    decorates: 'api_platform.openapi.factory'
    autoconfigure: false

将对示例 MyResource 名称的引用更改为您选择的资源名称(如 User)。

旁注: 在我看来,在 API 平台中自定义 OpenApi 端点文档的整个过程目前非常复杂。使用我提供的实现作为您自己实现的参考,因为您很可能需要对其进行一些调整以满足您的特定用例。