Fragments
The bookshop shows a "book card" in three places: the Browse page, search results and an author's page. Each card needs the same title, price and author name. Copying those fields into three queries works until someone adds a cover image to the card and forgets one of them. Fragments keep one definition.
The rule
Name a selection once, spread it wherever that type appears.
A fragment is a named, reusable selection set tied to a type:
fragment BookCard on Book {
title
price
author { name }
}BookCardis its name.on Bookis its type condition: it may only be used where aBookis being selected.
Use it with a spread, three dots and the name:
query BrowsePage {
books(first: 10) {
...BookCard
}
}
query AuthorPage($id: ID!) {
author(id: $id) {
name
books {
...BookCard
}
}
}The spread is replaced by the fragment's fields, so the response has title, price and author keys directly. There is no BookCard key; fragments exist only in the query.
Rules the server checks:
- A spread must fit its place:
...BookCardinsideauthor { }fails, because anAuthorcan never be aBook. - Every fragment defined in a document must be used.
- Fragments cannot spread themselves, directly or in a loop.
There is also an inline fragment, ... on Book { title }, with a type condition but no name. It matters when a field can return several types, which the Schema section covers.
Frontend frameworks lean on fragments: each component declares the fragment it needs, and the page query spreads them. Change a component's fields and every page that shows it follows.
The shortcut
When you see repeated fields, extract, name, spread.
Extract
The same
title price author { name }sits underbooksand underauthor { books }. Both places select aBook.
The trap is spreading a fragment on the wrong type. Read the spread's surroundings: what type is being selected right here?
Drills
Answer fast — trust the rule.
Which line uses the BookCard fragment?
In fragment BookCard on Book, what does on Book do?
Where does title appear in the response of { books { ...BookCard } }?
Why is { book(id: "b1") { author { ...BookCard } } } rejected?
A document defines fragment ReviewBits on Review { rating } but no operation spreads it. What happens?
Remember
- Name a selection once, spread it wherever that type appears.
- Extract, name, spread, then check each spread fits its type.
- Trap: spreading on the wrong type, or defining a fragment nobody uses.
