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

问题描述

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

考虑下面的实体注解,在clock.schedule_unique(anim_right,0.5) 部分的openapi_contextbody.description根本没有任何作用,这让我有点生气......你应该知道我是使用去/标准化上下文,但这似乎并不相关,所以我将其排除在外。

responses.200.description

结果(蓝色块如预期,红色块不起作用):

enter image description here

在这个问题上花了太多时间,如果有人能帮我解决这个问题,我真的很感激。我已经检查/尝试了以下无济于事;

作曲家版本(相关部分):


/**
 * 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
{
    ...
}

解决方法

经过一些试验,我发现 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,// 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',[],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 端点文档的整个过程目前非常复杂。使用我提供的实现作为您自己实现的参考,因为您很可能需要对其进行一些调整,使其满足您的特定用例。