Как запросить дополнительные параметры GET в конечной точке API-платформы с помощью документации swagger?

У меня есть проект 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:

Как запросить дополнительные параметры GET в конечной точке API-платформы с помощью документации swagger?

Но параметр страница теперь единственный параметр, который можно редактировать в веб-версии.

Мне нужно добавить больше параметров (в данном случае level) в swagger и опишите их, чтобы пользователь / тестировщик знал, какой параметр на самом деле идет к этой конечной точке.

Главный вопрос:

Как сообщить api-платформе, что я хочу, чтобы пользователь / тестировщик API (со стороны клиента) ввел некоторые другие параметры, например, level?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
13
0
7 923
5

Ответы 5

Наконец разобрался.

Я еще не нашел к нему документации, но нашел способ.

В классе сущности 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_context" на "openapi_context", если вы используете последние версии

Dom 26.11.2020 07:55

Внимание, "required" = "true" работает, потому что строка "true" имеет значение true. "required" = "false" не работает, это должен быть "required" = false

Fabian Schmengler 30.04.2021 12:08

И документация здесь: swagger.io/docs/specification/describing-parameters Документация по платформе Api не слишком охватывает спецификацию Swagger / OpenAPI.

Fabian Schmengler 30.04.2021 12:10

Добавление 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);
    }
}

Примечание:

  1. У меня также autowire и autoconfig установлены на true в services.yaml.

  2. Я добавил настраиваемого поставщика данных, чтобы требовать, чтобы фильтр свойств события был установлен во всех запросах 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>

Что дает вам это:

resulting swagger UI

Вы должны написать, где этот контент должен быть добавлен.

COil 11.11.2020 17:55

@COil Вы про расположение файлов конфигурации? Думаю, это немного выходит за рамки вопроса. Этот вопрос будет примерно таким: «Как я могу настроить ресурсы Api-Platform без использования аннотаций?»

yivi 11.11.2020 17:56

Если кто-то попадает сюда, ожидая дополнительного параметра GET в URL-адресе, например, если ваш параметр маршрутизации {id} не анализируется инструментом проверки swagger, вы должны просто изменить это в решении @pedrouan:

"in" = "path",

Используйте openapi_context и обратитесь к документации OpenAPI:

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

Другие вопросы по теме