У меня есть проект symfony, где я использую api-платформу.
У меня есть сущность, и у меня есть поставщики данных для нее. У меня проблемы с определением дополнительных параметров для конечной точки коллекции.
Сущность называется внушением. Он должен возвращать коллекцию документов из эластичного поиска.
Конечная точка:
/suggestion
Эта конечная точка прослушивает дополнительные параметры GET:
page, level
Эти два параметра считываются каждый раз, когда запрашивается конечная точка.
В моем классе 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
Параметр Страница - параметр по умолчанию, который генерируется в swagger для коллекций.
Скриншот с платформы API сгенерировал документ Swagger:
Но параметр страница теперь единственный параметр, который можно редактировать в веб-версии.
Мне нужно добавить больше параметров (в данном случае level) в swagger и опишите их, чтобы пользователь / тестировщик знал, какой параметр на самом деле идет к этой конечной точке.
Как сообщить api-платформе, что я хочу, чтобы пользователь / тестировщик API (со стороны клиента) ввел некоторые другие параметры, например, level?






Наконец разобрался.
Я еще не нашел к нему документации, но нашел способ.
В классе сущности 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:
Внимание, "required" = "true" работает, потому что строка "true" имеет значение true. "required" = "false" не работает, это должен быть "required" = false
И документация здесь: swagger.io/docs/specification/describing-parameters Документация по платформе Api не слишком охватывает спецификацию Swagger / OpenAPI.
Добавление swagger_context в аннотацию get не помогло мне в версии ядра Api Platform 2.4.6. Вместо этого я использовал инструкции, представленные на Платформа 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);
}
}
Примечание:
У меня также autowire и autoconfig установлены на true в services.yaml.
Я добавил настраиваемого поставщика данных, чтобы требовать, чтобы фильтр свойств события был установлен во всех запросах API к ресурсу сущности действия. Вышеупомянутая настройка не требует ее установки при выполнении запросов прямой выборки или получения URL.
Если кому-то нужно сделать что-то подобное, но с использованием конфигурации 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>
Что дает вам это:
Вы должны написать, где этот контент должен быть добавлен.
@COil Вы про расположение файлов конфигурации? Думаю, это немного выходит за рамки вопроса. Этот вопрос будет примерно таким: «Как я могу настроить ресурсы Api-Platform без использования аннотаций?»
Если кто-то попадает сюда, ожидая дополнительного параметра GET в URL-адресе, например, если ваш параметр маршрутизации {id} не анализируется инструментом проверки swagger, вы должны просто изменить это в решении @pedrouan:
"in" = "path",
Используйте openapi_context и обратитесь к документации OpenAPI:
* "openapi_context" = {
* "parameters" = {
* {
* "name" = "nameOfQueryParameter",
* "in" = "query",
* "description" = "Description goes here",
* "schema" = {
* "type" = "string"
* }
* }
* }
* }
Измените "swagger_context" на "openapi_context", если вы используете последние версии