Von der 300-Zeilen-Query zu kolokierten, wartbaren Bausteinen
Eine Seiten-Query, die alle Felder für zehn Komponenten in einem Block auflistet, wird bei jeder Änderung zum Merge-Konflikt-Magneten. GraphQL Fragments zerlegen Queries in benannte, wiederverwendbare Bausteine, die direkt neben der Komponente leben, die sie konsumiert, und lösen damit Wartbarkeitsprobleme, die mit wachsender Anwendung unvermeidlich werden.
Inhaltsverzeichnis
- 1. Warum große Queries ohne Fragments unwartbar werden
- 2. Fragment-Syntax: fragment Name on Type
- 3. Fragment Colocation: Fragments neben Komponenten
- 4. Fragmente kombinieren: Spreads und Verschachtelung
- 5. Fragmente auf Interfaces und Union Types anwenden
- 6. Fragment-Duplizierung vermeiden
- 7. Codegen aus Fragmenten: typsichere Fragment-Typen
- 8. Fragment Masking in Apollo Client und urql
- 9. Fragments im Vergleich zu Inline-Queries
- 10. Zusammenfassung
- 11. FAQ
1. Warum große Queries ohne Fragments unwartbar werden
Eine typische Seiten-Query in einer wachsenden React-Anwendung sammelt Felder für jede Komponente, die auf der Seite gerendert wird, Header, Produktkarte, Warenkorb-Widget, Footer. Ohne GraphQL Fragments landen all diese Felder in einer einzigen, monolithischen Query am Seiten-Einstiegspunkt, oft hunderte Zeilen lang. Jede Änderung an einer einzelnen Komponente erfordert eine Änderung an dieser zentralen Query, unabhängig davon, wie tief die Komponente im Baum verschachtelt ist.
Das Resultat sind Merge-Konflikte zwischen Teammitgliedern, die an unterschiedlichen Komponenten derselben Seite arbeiten, und eine Query, die niemand mehr vollständig überblickt. GraphQL Fragments lösen dieses Problem strukturell: Jede Komponente deklariert genau die Felder, die sie selbst benötigt, in einem eigenen, benannten Fragment. Die übergeordnete Query kombiniert diese Fragmente lediglich, ohne die Feldliste jeder einzelnen Komponente zu kennen.
2. Fragment-Syntax: fragment Name on Type
Die Grundsyntax eines GraphQL Fragment ist denkbar einfach: fragment FragmentName on TypeName { felder }. Der Typname nach on legt fest, auf welchen GraphQL-Typ das Fragment anwendbar ist, die Feldliste innerhalb der geschweiften Klammern folgt exakt derselben Syntax wie in einer normalen Query. Ein Fragment kann anschließend mit der Spread-Syntax ...FragmentName in jede Query oder in jedes andere Fragment eingebunden werden, das denselben oder einen kompatiblen Typ erwartet.
fragment ProductCardFields on Product {
id
name
sku
price
thumbnailUrl
}
query ProductListPage {
products(first: 20) {
edges {
node {
...ProductCardFields
}
}
}
}
Der Vorteil zeigt sich sofort bei Wiederverwendung: ProductCardFields lässt sich in jeder Query einbinden, die eine Produktkarte rendert, egal ob Produktliste, Suchergebnis oder verwandte Produkte. Ändert sich die Produktkarte um ein neues Feld, wird nur das Fragment einmalig angepasst, jede Query, die es einbindet, erhält das neue Feld automatisch, ohne selbst geändert werden zu müssen.
3. Fragment Colocation: Fragments neben Komponenten
Das Fragment Colocation Pattern geht einen Schritt weiter als reine Wiederverwendung: Statt Fragments in einer zentralen Datei zu sammeln, wird das Fragment einer Komponente direkt in derselben Datei wie die Komponente selbst definiert. Die Komponente deklariert exakt, welche Daten sie benötigt, unmittelbar neben dem Code, der diese Daten rendert. Das reduziert die kognitive Distanz zwischen Datenanforderung und Datennutzung auf null.