Directives
The book page has a "Show reviews" toggle. When it is off, fetching reviews is wasted work. You could keep two nearly identical queries, one with reviews and one without, but a directive lets one query switch its own parts on and off.
The rule
@includekeeps when true;@skipdrops when true.
A directive is an @name with optional arguments, attached to part of a document to change how it is handled. Every GraphQL server supports two in queries:
@include(if: Boolean!): the field or fragment is kept only whenifistrue.@skip(if: Boolean!): the field or fragment is dropped whenifistrue.
They are almost always fed by a variable:
query BookPage($id: ID!, $withReviews: Boolean!) {
book(id: $id) {
title
price
reviews(first: 5) @include(if: $withReviews) {
rating
text
}
}
}{ "id": "b1", "withReviews": false }With withReviews false, the server never runs the reviews resolver, and the response has no reviews key at all: not null, not an empty list, simply absent.
Directives can sit on a field, a fragment spread or an inline fragment:
...ReviewLine @skip(if: $compact)If a field carries both, it is kept only when @skip is false and @include is true.
Directives also appear in schemas, where they describe the API rather than a request. The best-known is @deprecated:
type Book {
isbn: String @deprecated(reason: "Use isbn13.")
isbn13: String
}Servers and tools can define their own directives too, but @include, @skip and @deprecated are the ones every GraphQL user meets.
The shortcut
To predict a field, evaluate the condition, then read the name: include + true = kept; skip + true = gone.
Toggle off
$withReviewsis false.@include(if: false)dropsreviews, so the response has onlytitleandprice.
The trap is expecting null for a dropped field. A skipped field is missing from the response, so frontend code should check for the key, not for null.
Drills
Answer fast — trust the rule.
With $withReviews false, what does reviews @include(if: $withReviews) { rating } produce?
Which directive drops a field when its condition is true?
A field has @skip(if: false) @include(if: false). Is it in the response?
Where does @deprecated normally appear?
Remember
@includekeeps when true;@skipdrops when true.- Evaluate the condition, then read the name; with both, skip must be false and include true.
- Trap: a dropped field is missing, not
null.
