I'm trying to define an entity with multiple endpoints using Api Platform. When I try to define multiple Get or GetCollection endpointd, it returns a 404 error. Looking for the reason, the only conclusion I can find was a bad uriTemplate definition, but does not make sense to me.
I try the next and it work, but I don't understand why.
If I define the endpoint like /sport_centers_top_rated it worksIf I define the endpoint like /sport_centers/top_rated it does not work.
I can don't understand why.
Here is my class definition:
<?phpnamespace App\Entity\App;use ApiPlatform\Metadata\ApiResource;use ApiPlatform\Metadata\Delete;use ApiPlatform\Metadata\Get;use ApiPlatform\Metadata\GetCollection;use ApiPlatform\Metadata\Post;use ApiPlatform\Metadata\Put;use App\Controller\App\SportCenter\SportCenterCreateController;use App\Controller\App\SportCenter\SportCenterDeleteController;use App\Controller\App\SportCenter\SportCenterReadController;use App\Controller\App\SportCenter\SportCenterUpdateController;use App\Entity\Master\City;use App\Repository\App\SportCenterRepository;use App\Traits\Entity\DatetimeTrait;use Doctrine\Common\Collections\ArrayCollection;use Doctrine\Common\Collections\Collection;use Doctrine\ORM\Mapping as ORM;use Symfony\Component\Serializer\Attribute\Groups;#[ORM\Table(schema: 'app')]#[ORM\Entity(repositoryClass: SportCenterRepository::class)]#[ORM\HasLifecycleCallbacks]#[ApiResource( operations: [ new Get( name: 'sport_center:read' ), new Get( uriTemplate: '/sport_centers/{id}/sports', controller: SportCenterReadController::class, name: 'sport_center:read:sport_types' ), new Get( uriTemplate: '/sport_centers/{id}/reserves_availability', controller: SportCenterReadController::class, name: 'sport_center:read:reserves_availability' ), new GetCollection( uriTemplate: '/sport_centers', controller: SportCenterReadController::class, name: 'sport_center:read:list' ), new GetCollection( uriTemplate: '/sport_centers/top_reserves', controller: SportCenterReadController::class, normalizationContext: ['groups' => ['sport_center:read:top_rated' ] ], name: 'sport_center:read:list:top_reserves' ), new Post( uriTemplate: '/sport_centers', controller: SportCenterCreateController::class, name: 'sport_center:write:create' ), new Put( uriTemplate: '/sport_centers/{id}', controller: SportCenterUpdateController::class, denormalizationContext: ['groups' => ['sport_center:write:update', ] ], name: 'sport_center:write:update' ), new Delete( uriTemplate: '/sport_centers/{id}', controller: SportCenterDeleteController::class, name: 'sport_center:write:delete' ), ], normalizationContext: ['groups' => ['sport_center:read', ] ], denormalizationContext: ['groups' => ['sport_center:write', ] ])]class SportCenter{ use DatetimeTrait; #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] #[Groups( groups: ['sport_center:read','court:write','court:read','reserve:read','reserve:read:search_reserves','city:read' ] )] private int $id; #[ORM\Column(length: 255)] #[Groups( groups: ['sport_center:write','sport_center:read','court:read','sport_center:write:update','reserve:read','reserve:read:search_reserves','city:read' ] )] private string $name; #[ORM\Column(length: 255)] #[Groups( groups: ['sport_center:write','sport_center:read','court:read','reserve:read','sport_center:write:update','city:read' ] )] private string $street; #[ORM\Column(length: 255)] #[Groups( groups: ['sport_center:write','sport_center:read','court:read','sport_center:write:update', ] )] private string $postalCode; #[ORM\OneToMany(mappedBy: 'sportCenter', targetEntity: Court::class, cascade: ['persist', 'remove'], orphanRemoval: true)] #[Groups( groups: ['sport_center:read','sport_center:read:details:admin' ] )] private Collection $courts; #[ORM\ManyToOne(inversedBy: 'sportCenters')] #[ORM\JoinColumn(nullable: false)] private User $admin; #[ORM\ManyToOne(inversedBy: 'sportCenters')] #[Groups( groups: ['sport_center:write','sport_center:read','court:read','sport_center:write:update','reserve:read','reserve:read:search_reserves' ] )] private City $city; public function __construct() { $this->courts = new ArrayCollection(); } public function getId(): ?int { return $this->id; } public function getName(): ?string { return $this->name; } public function setName(string $name): self { $this->name = $name; return $this; } public function getStreet(): ?string { return $this->street; } public function setStreet(string $street): self { $this->street = $street; return $this; } public function getPostalCode(): ?string { return $this->postalCode; } public function setPostalCode(string $postalCode): self { $this->postalCode = $postalCode; return $this; } /** * @return Collection<int, Court> */ public function getCourts(): Collection { return $this->courts; } public function addCourt(Court $court): self { if (!$this->courts->contains($court)) { $this->courts->add($court); $court->setSportCenter($this); } return $this; } public function removeCourt(Court $court): self { if ($this->courts->removeElement($court)) { // set the owning side to null (unless already changed) if ($court->getSportCenter() === $this) { $court->setSportCenter(null); } } return $this; } public function getAdmin(): ?User { return $this->admin; } public function setAdmin(?User $admin): self { $this->admin = $admin; return $this; } public function getCity(): ?City { return $this->city; } public function setCity(?City $city): static { $this->city = $city; return $this; } public function getSportTypes(): array { $sports = []; foreach ($this->courts as $court) { $sports[] = $court->getSport()->value; } return array_unique($sports); } #[Groups(['sport_center:read' ])] public function getNCourts() { return sizeof($this->getCourts()); }}