Verschachtelte Collections: /api/projects/{id}/tasks
Verschachtelte Collections: /api/projects/{id}/tasks
~14 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026
NEBEN /api/tasks (ALLE Tasks) lohnt sich oft ein ZWEITER Endpunkt, der NUR die Tasks EINES bestimmten Projekts liefert – GENAU dafür gibt es verschachtelte ("sub-resource") Operationen.
Eine verschachtelte Operation definieren
use ApiPlatform\Metadata\GetCollection;
#[ApiResource(
normalizationContext: ['groups' => ['task:read']],
denormalizationContext: ['groups' => ['task:write']]
)]
#[ApiResource(
uriTemplate: '/projects/{projectId}/tasks',
uriVariables: [
'projectId' => new \ApiPlatform\Metadata\Link(
fromClass: Project::class,
toProperty: 'project',
),
],
operations: [new GetCollection()],
normalizationContext: ['groups' => ['task:read']]
)]
#[ORM\Entity(repositoryClass: TaskRepository::class)]
class Task
{
// ... unverändert
}ZWEI #[ApiResource]-Attribute auf DERSELBEN Klasse – das ERSTE definiert die "flache" /api/tasks-Resource aus Kapitel 37, das ZWEITE eine ZUSÄTZLICHE, verschachtelte Sicht auf DIESELBEN Daten.
Link erklärt
Link beschreibt, WIE der Platzhalter {projectId} mit einer echten Datenbankabfrage verbunden wird: fromClass: Project::class sagt, DASS projectId eine Project-ID ist, toProperty: 'project' sagt, DASS auf der Task-Seite über die project-Property gefiltert wird.
Den verschachtelten Endpunkt testen
curl -k https://localhost/api/projects/1/tasks{
"@context": "/api/contexts/Task",
"@id": "/api/projects/1/tasks",
"@type": "hydra:Collection",
"hydra:member": [
{"@id": "/api/tasks/1", "title": "Wireframes erstellen", "done": false}
],
"hydra:totalItems": 1
}NUR Tasks von Projekt 1 – EXAKT dieselbe Filterung wie manuell mit ?project=/api/projects/1 (Kapitel 31 ließe sich dafür auch nutzen), aber als EIGENER, sprechenderer Pfad.
Achtung: Ein Aufruf von /api/projects/999/tasks mit einer NICHT existierenden projectId liefert 404 Not Found – API Platform prüft AUTOMATISCH, ob das übergeordnete Project existiert, BEVOR die Task-Collection abgefragt wird.
Tipp: ALLE Filter/Pagination/Sortierung aus Block 4 funktionieren AUCH auf verschachtelten Collections – /api/projects/1/tasks?order[title]=asc ist GENAUSO gültig wie auf der flachen /api/tasks-Resource.