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.