IRI vs. eingebettete Objekte
IRI vs. eingebettete Objekte
~14 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026
Kapitel 37-38 zeigten Beziehungen IMMER als IRI-STRINGS ("/api/tasks/1") – dieses Kapitel erklärt WARUM, und WIE sich das GEZIELT zu eingebetteten Objekten ändern lässt.
Warum IRIs der Standard sind
- EFFIZIENZ: eine Liste von 45 Projekten mit JEWEILS eingebetteten Tasks würde die Antwortgröße DRASTISCH aufblähen, selbst wenn das Frontend die Tasks GAR NICHT braucht.
- KONSISTENZ: eine IRI ist IMMER die AKTUELLE, VOLLSTÄNDIGE Repräsentation EINES Klicks entfernt – kein Risiko VERALTETER eingebetteter Daten.
- HYPERMEDIA-PRINZIP: JSON-LD/Hydra basiert DARAUF, dass Clients Ressourcen über LINKS statt über eingebettete Kopien navigieren (GENAU wie HTML-Links im Web).
Gezielt einbetten mit verschachtelten Gruppen
#[ORM\ManyToOne(inversedBy: 'tasks')]
#[ORM\JoinColumn(nullable: false)]
#[Groups(['task:read', 'task:write', 'task:read:embedded'])]
private ?Project $project = null;EINE zusätzliche Gruppe wie task:read:embedded reicht NICHT allein aus – die ZIEL-Entity (Project) braucht auf IHREN eigenen Properties (id, name) EBENFALLS diese Gruppe, DAMIT sie SICHTBAR werden, sobald eingebettet wird.
Die context-Option pro Operation
new Get(
normalizationContext: ['groups' => ['task:read', 'task:read:embedded']],
),NUR bei GET /api/tasks/{id} (EIN einzelnes Element) wird das Project EINGEBETTET, bei GetCollection BLEIBT es eine IRI – eine GÄNGIGE Praxis: Details EINES Elements liefern MEHR, eine Liste bleibt SCHLANK.
Das Ergebnis vergleichen
| Anfrage | project-Feld |
|---|---|
GET /api/tasks (Collection) | "project": "/api/projects/1" |
GET /api/tasks/1 (Item, MIT embedded-Gruppe) | "project": {"@id": "/api/projects/1", "id": 1, "name": "Website-Relaunch"} |
Achtung: Eingebettete Objekte VERMEIDEN, wenn die Beziehung ZIRKULÄR werden könnte (Project bettet Tasks ein, die WIEDERUM ihr Project einbetten würden) – Kapitel 45 zeigt GEZIELT, wie man das VERMEIDET.
Tipp: React (Block 9) profitiert davon, dass IRIs GLEICHZEITIG gültige URLs sind – ein fetch(task.project) funktioniert DIREKT, OHNE die ID erst aus einem Objekt herausklauben zu müssen.