Платформа API - как создать пользовательскую операцию сбора (GET)?

Я начинаю с платформы API, и мне нужно реорганизовать старый API, который не использовал платформу API. Я использую Symfony 5 и Doctrine, я выставляю объекты с аннотацией @Api Platform и вижу операции CRUD в документе API. Но мне нужно настроить несколько операций, и у меня есть некоторые трудности.

Прежде всего я хотел бы получить коллекцию предметов по определенному атрибуту.

Лицо :

/**
 * Parcsportif
 * @ApiResource(
 * collectionOperations = {"get"},
 * itemOperations = {"get"})
 *
 * @ORM\Table(name = "parcSportif", indexes = {@ORM\Index(name = "index_numSite", columns = {"numSite"})})
 * @ORM\Entity
 */
class Parcsportif
{
    /**
     * @var int
     * @ORM\Column(name = "numParc", type = "integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy = "IDENTITY")
     */
    private $numparc;

    /**
     * @var int
     * @ORM\Column(name = "numSite", type = "integer", nullable=false)
     */
    private $numsite = '0';

    // others attributes and getters and setters


Маршруты, генерируемые платформой Api:

  • / api / parcsportifs: коллекция GET
  • / api / parcsportifs / {numparc}: ПОЛУЧИТЬ элемент

Но я бы хотел изменить их так:

  1. / api / listeEquipements / {numsite}: ПОЛУЧИТЬ коллекцию по атрибуту numsite.
  2. / api / informationEquipement / {numparc}: ПОЛУЧИТЬ элемент

Итак, я изменил сущность следующим образом:

**
 * Parcsportif
 * @ApiResource(
 *      collectionOperations = {
 *     "get" = {
 *                  "method" = "GET",
 *                  "path" = "/listeEquipementsClient/{numsite}",
 *                  "openapi_context" = {
 *                      "parameters" = {
 *                          {
 *                              "name" = "numsite",
 *                              "in" = "path",
 *                              "description" = "numéro site",
 *                              "required" = true,
 *                              "schema" = {
 *                                  "type" : "integer"
 *                              },
 *                              "style" = "simple"
 *                          }
 *                      }
 *            },
 *              "controller" = ListeEquipementsController::class
 *       }
 *     },
 *     itemOperations = {"get" = {"path" = "/informationEquipement/{numparc}"}}
 * )

Контроллер выше:

class ListeEquipementsController
{
    private $parcSportifRepository;

    public function __construct(ParcSportifRepository $parcSportifRepository)
    {
        $this->parcSportifRepository = $parcSportifRepository;
    }

    public function __invoke($numsite): iterable
    {
        return $this->parcSportifRepository->getListeEquipementsParNumSite($numsite);
    }
}

И репозиторий для сущности:

class ParcSportifRepository extends ServiceEntityRepository
{
    private $em;

    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, Parcsportif::class);
        $this->em = $this->getEntityManager();
    }

    public function getListeEquipementsParNumSite($numSite): iterable
    {
        return $this->findBy([
            "numsite" => $numSite,
        ]);
    }
}

Итак, маршрут 2) операция «GET item» работает нормально, но при вызове маршрута 1) в Postman возникает следующая ошибка:

"Unable to generate an IRI for "App\Entity\Parcsportif"."

Я этого не понимаю.

Как я могу узнать, что не так?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
0
0
32
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

При указании /listeEquipementsClient/{numsite} в качестве пути вы сообщаете платформе API, что numsite является идентификатор вашего ресурса. Мало того, что numsite не является идентификатором ресурса (это numparc, что приводит к возникшей ошибке), операции GET сбора не должны ожидать ярлыки пути URL в качестве параметров фильтра, но вместо этого ожидают параметры запроса:

/parcsportifs?numsite=123

Это должно отфильтровать коллекцию Parcsportif для ресурсов, имеющих значение numsite, равное 123, и может быть достигнуто путем предоставления аннотации @ApiFilter к свойству Parcsportif::$numsite:

/**
 * @var int
 * @ORM\Column(name = "numSite", type = "integer", nullable=false)
 * @ApiFilter(
 *      SearchFilter::class,
 *      properties = {
 *          "numsite": "exact"
 *      }
 * )
 */
 private $numsite = '0';

Если вы действительно хотите реализовать конечные точки, описанные в вашем сообщении (используя numsite в качестве идентификатора ресурса), вам придется реализовать собственный ресурс и поставщик данных, поддерживающий numsite в качестве идентификатора для этого ресурса.

Фильтр реши мою проблему :) спасибо :) Это проще, чем поставщик данных

Romain Chalumeau 08.04.2021 17:52

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