Я начинаю с платформы 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:
Но я бы хотел изменить их так:
Итак, я изменил сущность следующим образом:
**
* 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"."
Я этого не понимаю.
Как я могу узнать, что не так?




При указании /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 в качестве идентификатора для этого ресурса.
Фильтр реши мою проблему :) спасибо :) Это проще, чем поставщик данных