Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

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

api/src/Entity/Task.php
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 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.