Optimising GraphQL queries with @include and @skip
Imagine you have a complex multi-faceted GraphQL query:
query(id: String) {
thing(id) {
foo {
...
}
bar {
...
}
}
}
In some GraphQL resolvers, this might be transformed into SQL queries on a database like so:
SELECT * FROM foo WHERE id = $id;
SELECT * FROM bar WHERE id = $id;
This may be fine if we always need data from both foo and bar. But if we do not always need data from both sources, it would be more efficient to ask for only what we need. This is where the @include
and @skip
directives come in handy. The @include
and @skip
directives allow you to conditionally include or exclude parts of a query based on variables, so resolvers are not called unnecessarily and we only end up getting the data that we want.
The @include
directive includes a field only if a specified condition is true, like so:
query($id: String, $includeFoo: Boolean!) {
thing(id: $id) {
foo @include(if: $includeFoo) {
...
}
bar {
...
}
}
}
With this query, the foo
field will only be fetched if the variable $includeFoo
is set to true
. This translates to the following SQL queries:
-- When $includeFoo is true:
SELECT * FROM foo WHERE id = $id;
SELECT * FROM bar WHERE id = $id;
-- When $includeFoo is false:
SELECT * FROM bar WHERE id = $id;
The @skip
directive works in the opposite way: it skips a field if a specified condition is true.