API Platform – How to create a custom collection operation (GET)?

  api-platform.com, symfony

I’m starting with API Platform and I have to refactor an old API that did not use API Platform. I’m using Symfony 5 and Doctrine, I exposed entities with annotation @Api Platform and I see CRUD operations on the API doc. But I have to customize several operations and I have some difficulties.

First of all I would like to get a collection of items by a specific attribute.

The entity :

/**
 * Parcsportif
 * @ApiResource(
 * collectionOperations={"get"},
 * itemOperations={"get"})
 *
 * @ORMTable(name="parcSportif", indexes={@ORMIndex(name="index_numSite", columns={"numSite"})})
 * @ORMEntity
 */
class Parcsportif
{
    /**
     * @var int
     * @ORMColumn(name="numParc", type="integer", nullable=false)
     * @ORMId
     * @ORMGeneratedValue(strategy="IDENTITY")
     */
    private $numparc;

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

    // others attributes and getters and setters


The routes generated by Api platform are :

  • /api/parcsportifs : GET collection
  • /api/parcsportifs/{numparc} : GET item

But I would like to modify them like this :

  1. /api/listeEquipements/{numsite} : GET collection by the ‘numsite’ attribute
  2. /api/informationEquipement/{numparc} : GET item

So I changed the entity like this :

**
 * 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}"}}
 * )

The controller above is :

class ListeEquipementsController
{
    private $parcSportifRepository;

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

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

And the repository for the entity :

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,
        ]);
    }
}

So the route 2) the operation "GET item" works fine, but I have the following error when I call the route 1) on Postman :

"Unable to generate an IRI for "AppEntityParcsportif"."

I don’t understand it.

How can I find what’s wrong?

Source: Symfony Questions

LEAVE A COMMENT