如何使用 swagger 文档在 api 平台端点中请求额外的 GET 参数?

问题描述 投票:0回答:9

我有一个 symfony 项目,我在其中使用 api-platform。

我有一个实体,并且有它的数据提供者。我在定义集合端点的附加参数时遇到麻烦。

一个实体称为建议。它必须从弹性搜索返回文档集合。

终点是:

/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 文档的屏幕截图:

enter image description here

但是page参数现在是唯一可以在网页版中编辑的参数

我需要向 swagger 添加更多参数(在本例中为

level
)并描述它们,以便用户/测试人员知道哪个参数实际到达此端点。

主要问题:

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

php symfony swagger openapi api-platform.com
9个回答
15
投票
终于明白了。

我还没有找到它的文档,但我找到了一种方法。

在实体类中

Suggestion.php

我添加了一些
注释行

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 中的结果视图:

enter image description here


4
投票
在 Api Platform 核心版本 2.4.6 中,将“swagger_context”添加到 get 注释对我来说不起作用。相反,我使用了提供的说明

API 平台 - 覆盖 OpenAPI 规范

就我而言,我不得不稍微偏离说明。在重写的标准化方法中,我必须首先删除现有参数,然后将自定义定义添加到 $doc 参数数组中。正如 pedrouan 所做的那样,我能够添加 required=true 属性,并且它以相同的方式工作。

在 services.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。

  2. 我添加了一个自定义数据提供程序,要求在对活动实体资源的所有 api 请求中设置事件属性过滤器。上述定制不需要在进行直接 fetch 或 url get 请求时设置。


3
投票
瞧,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 ),
    

2
投票
使用openapi_context并参考OpenAPI文档:

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

1
投票
如果有人最终期望 URL 中包含额外的 GET 参数,例如,如果 swagger 测试工具未解析您的路由 {id} 参数,您应该在 @pedrouan 解决方案中更改此设置:

"in" = "path",
    

1
投票
您可以像 ApiPlatform 文档中看到的那样使用 Filter (

https://api-platform.com/docs/core/filters/)。

例如,对于我的地址模型,我只使用 ApiPlatform 核心中的学说桥 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 }
将会导致

Result

希望它可以帮助别人!


0
投票
如果有人需要做类似的事情,但使用 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>
这会给你带来这个:

resulting swagger UI


0
投票
您最好创建一个自定义过滤器来描述附加参数。

这将为您提供所需的 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 平台文档中没有对此进行描述,但是,这里是当前的文档链接:

https://api-platform.com/docs/core/filters/#creating-custom-filters

注意实现正确的接口;)


0
投票
自 ApiPlatform 3.3 以来,情况略有变化。您应该使用

openapi_context

parameters
 而不是 
QueryParameter
:

new GetCollection( uriTemplate: '/example/custom', controller: ExampleCustomAction::class, name: 'custom', parameters: [ 'param_name' => new QueryParameter( required: true, description: 'Param description', schema: ['type' => 'string'] ), ], )
请注意如何声明类型:

schema: ['type' => 'string']
因此它将被正确传递给 

openapi.yaml

|
openapi.json
 如果您需要的话。

顺便说一句,使用

openapi_context

 时,您也应该使用 
schema
,而不是直接使用 
type

© www.soinside.com 2019 - 2024. All rights reserved.