如何使用swagger docs在api-platform的端点中请求额外的GET参数?

7jmck4yq  于 2023-08-05  发布在  其他
关注(0)|答案(8)|浏览(147)

我有一个symfony项目,在那里我使用api平台。
我有一个实体,我有它的数据提供者。我在定义收集端点的附加参数时遇到了麻烦。
一个实体被称为建议。它必须从ElasticSearch返回文档集合。
端点是:

/suggestion

字符串
此端点侦听其他GET参数:
页面,级别
这两个参数在每次请求端点时都被读取。
在我的SuggestionsCollectionDataProvider.php类中,我有:

/**
     * Retrieves a collection.
     *
     * @param string $resourceClass
     * @param string|null $operationName
     * @return \Generator
     */
    public function getCollection(string $resourceClass, string $operationName = null): \Generator
    {
        $query = $this->requestStack->getCurrentRequest()->query;
        // I am reading these two parameters from RequestStack
        
        // this one is built-in
        $page = max($query->get('page', 1), 1); 

        // this is a custom one
        $level = $query->get('level', 0); 
        ...


SuggestionRepository.php类中:

/**
     * @return \Generator
     */
    public function find(int $page, int $level): \Generator
    {
        // here I can process with $level without problems

Page参数为默认参数,在swagger中为集合生成。

API平台生成的Swagger文档截图:
x1c 0d1x的数据
page参数现在是唯一的参数,在web版中可以编辑。

我需要向swagger添加更多的参数(在本例中为level)并描述它们,以便用户/测试人员知道哪个参数实际上到达该端点。

主要问题:

如何告诉api-platform,我希望API的用户/测试人员(从客户端)输入一些其他参数,即例如level

nbysray5

nbysray51#

终于想通了。
我还没有找到相关的文档,但我找到了一种方法。
在一个实体类Suggestion.php中,我添加了几行annotations

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiProperty;
use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Class Suggestion. Represents an entity for an item from the suggestion result set.
 * @package App\Entity
 * @ApiResource(
 *     collectionOperations={
 *          "get"={
 *              "method"="GET",
 *              "swagger_context" = {
 *                  "parameters" = {
 *                      {
 *                          "name" = "level",
 *                          "in" = "query",
 *                          "description" = "Levels available in result",
 *                          "required" = "true",
 *                          "type" : "array",
 *                          "items" : {
 *                              "type" : "integer"
 *                          }
 *                      }
 *                  }
 *               }
 *          }
 *     },
 *     itemOperations={"get"}
 * )
 */

字符串
API平台swagger DOC中的结果视图:


的数据

jhkqcmku

jhkqcmku2#

在API平台核心版本2.4.6中,向get注解添加“swagger_context”对我不起作用。相反,我使用了API平台-覆盖OpenAPI规范中提供的说明
在我的情况下,我不得不稍微偏离说明。在重写的normalize方法中,我必须首先删除现有参数,然后将自定义添加到$doc参数数组中。正如pedrouan所做的那样,我能够添加required=true属性,并且它以相同的方式工作。
在服务.yaml我补充说:

App\Swagger\SwaggerEventRequireDecorator:
         decorates: 'api_platform.swagger.normalizer.api_gateway'
         arguments: [ '@App\Swagger\SwaggerEventRequireDecorator.inner' ]
         autoconfigure: false

字符串
在App\Swagger文件夹中,我添加了以下类:

<?php

namespace App\Swagger;

use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

final class SwaggerEventRequireDecorator implements NormalizerInterface
{
    private $decorated;

    public function __construct(NormalizerInterface $decorated)
    {
        $this->decorated = $decorated;
    }

    public function normalize($object, $format = null, array $context = [])
    {
        $docs = $this->decorated->normalize($object, $format, $context);

        $customDefinition = [
            'name' => 'event',
            'description' => 'ID of the event the activities belong to.',
            'in' => 'query',
            'required' => 'true',
            'type' => 'integer'
        ];

//         e.g. remove an existing event parameter
        $docs['paths']['/scheduleamap-api/activities']['get']['parameters'] = array_values(array_filter($docs['paths']['/scheduleamap-api/activities']['get']['parameters'], function ($param) {
            return $param['name'] !== 'event';
        }));

    // e.g. add the new definition for event
    $docs['paths']['/scheduleamap-api/activities']['get']['parameters'][] = $customDefinition;

        // Remove other restricted parameters that will generate errors.
        $docs['paths']['/scheduleamap-api/activities']['get']['parameters'] = array_values(array_filter($docs['paths']['/scheduleamap-api/activities']['get']['parameters'], function ($param) {
            return $param['name'] !== 'event[]';
        }));

        return $docs;
    }

    public function supportsNormalization($data, $format = null)
    {
        return $this->decorated->supportsNormalization($data, $format);
    }
}


注意事项:
1.我还在services. yaml中将autowire和autoconfig设置为true。
1.我添加了一个自定义数据提供程序,要求在所有对活动实体资源的API请求中设置事件属性过滤器。上面的自定义在进行直接获取或url get请求时不需要设置它。

gkn4icbw

gkn4icbw3#

如果有人在这里期望URL中有一个额外的GET参数,例如如果你的路由{id}参数没有被swagger测试工具解析,你应该在@pedrouan解决方案中更改它:

"in" = "path",

字符串

fbcarpbf

fbcarpbf4#

如果有人需要做类似的事情,但使用XML配置:

<collectionOperation name="find_duplicated_items">
    <attribute name="method">GET</attribute>
    <attribute name="path">/items/find_duplicates</attribute>
    <attribute name="controller">App\Infrastructure\Http\Items\FindDuplicates</attribute>

     <attribute name="openapi_context">
        <attribute name="parameters">

            <attribute>
                <attribute name="name">someProperty</attribute>
                <attribute name="in">query</attribute>
                <attribute name="required">true</attribute>
                <attribute name="description">List foos and bars</attribute>
                <attribute name="schema">
                     <attribute name="type">array</attribute>
                     <attribute name="items">
                        <attribute name="type">integer</attribute>
                     </attribute>
                </attribute>
            </attribute>
        
            <attribute>
                <attribute name="name">ageDays</attribute>
                <attribute name="in">query</attribute>
                <attribute name="required">false</attribute>
                <attribute name="description">Max age in days</attribute>
                <attribute name="default">5</attribute>
                <attribute name="schema">
                    <attribute name="type">integer</attribute>
                </attribute>
            </attribute>
        </attribute>

    </attribute>

</collectionOperation>

字符串
所以你得到了这个:


的数据

nukf8bse

nukf8bse5#

使用openapi_context并参考OpenAPI文档:

*              "openapi_context" = {
 *                  "parameters" = {
 *                      {
 *                          "name" = "nameOfQueryParameter",
 *                          "in" = "query",
 *                          "description" = "Description goes here",
 *                          "schema" = {
 *                              "type" = "string"
 *                          }
 *                      }
 *                  }
 *               }

字符串

qyzbxkaa

qyzbxkaa6#

最好创建一个自定义过滤器来描述附加参数。
这将为您提供所需的openApi文档条目,其优点是api-platform还将自动应用您在过滤器类中描述的验证约束。此外,您还可以使用经过净化的(或不经过净化的)值来丰富上下文。

<?php

namespace App\Filter;

use ApiPlatform\Core\Serializer\Filter\FilterInterface;
use Symfony\Component\HttpFoundation\Request;

class MyParamFilter implements FilterInterface
{
    public const MYPARAM_FILTER_CONTEXT = 'myparam';

    public function getDescription(string $resourceClass): array
    {
        $doc = [
            'allowEmptyValue' => false,
            'example' => 'blabla',
        ];
        $schema = [
            'type' => 'string',
            'minLength' => 2,
            'maxLength' => 32,
        ];

        return [
            'myparam' => [
                'description' => 'Parameter description',
                'property' => null,
                'type' => 'string',
                'required' => true,
                'swagger' => array_merge(
                    $doc,
                    $schema
                ),
                'openapi' => array_merge(
                    $doc,
                    [
                        'schema' => $schema,
                    ]
                ),
            ],
        ];
    }

    public function apply(Request $request, bool $normalization, array $attributes, array &$context): void
    {
        $context[self::MYPARAM_FILTER_CONTEXT] = $request->query->get('myparam');
    }
}

字符串
api-platform文档中没有描述这一点,但这里是当前的文档链接:
https://api-platform.com/docs/core/filters/#creating-custom-filters的网站。
注意实现正确的接口;)

t40tm48m

t40tm48m7#

您可以像在ApiPlatform文档(https://api-platform.com/docs/core/filters/)中看到的那样使用Filter。
例如,对于我的地址模型,我只使用ApiPlatform核心的Doctrine Bridge SearchFilter

/**
 * Class Address
 *
 * @ORM\Entity
 */
#[ApiResource]
#[ApiFilter(SearchFilter::class, properties: ['street' => 'partial'])]
class Address
{
    /**
     * @var string|null $street
     *
     * @ORM\Column(type="string", nullable=true)
     */
    private ?string $street;

   // Do some fancy things here
}

字符串
这将导致
x1c 0d1x的数据
希望能帮到人!

mgdq6dx1

mgdq6dx18#

Voilà la version avec les attributs PHP8:

new GetCollection(
        uriTemplate: '/products',
        controller: GetProductsCollection::class,
        openapiContext: [
            'parameters' => [
                [
                    'name'        => 'page',
                    'in'          => 'query',
                    'description' => 'Collection page number',
                    'required'    => false,
                    'type'        => 'integer',
                    'default'     => 1,
                ],
                [
                    'name'        => 'rows',
                    'in'          => 'query',
                    'description' => 'Max rows',
                    'required'    => false,
                    'type'        => 'integer',
                    'default'     => 50,
                ],
            ],
        ],
        read: false
    ),

字符串

相关问题