A simple GraphQL query looks like this:
query myQuery() {
user {
age
firstName
lastName
dob
}
}
Above query returns response of the format
data {
user {
age: 23,
firstName: "John",
lastName: "Smith",
dob: "01-01-1970"
}
}
Well, this is pretty standard stuff. GraphQL endpoint returns the exact fields are requested.
Now, what if I want to query different fields every time ? For eg, I want to query { age, firstName }
first time and then { age, dob }
. I wouldn't want to fetch firstName
in second case since I won't be needing it. This is a solid approach especially when an API call is involved with certain fields.
Usecases for this would be when
- There is a checklist on the UI containing which data elements need to be fetched.
- User selects his authorisation criteria and we want to fetch just that.
One way to do this would be to generate queries depending on the fields specified. But this gets pretty messy as soon as we introduce nested jsons.
To solve this, GraphQL has a very handy feature called directives. Very specifically, @include
directive solves the problem of dynamic querying.
Now, we will rewrite the above query using @include
directive.
query myQuery($age: Boolean!, $firstName: Boolean!, $lastName: Boolean!, $dob: Boolean!) {
user {
age @include(if: $age)
firstName @include(if: $firstName)
lastName @include(if: $lastName)
dob @include(if: $dob)
}
}
variables:
{
age: true,
firstName: true,
lastName: false,
dob: false
}
The response of the above query would be:
data {
user {
age: 23,
firstName: "John"
}
}
It returns just age
and firstName
since only those were set to true
in the variables json. Another good thing about this @include
directive is, GraphQL engine do not even execute the corresponding resolvers thus gaining us performance. Manipulating these variables json is very simple and the query will not need be mutated for every request. To get the values of dob
instead of firstName
, we just need to change firstName: false
and dob: true
in variables json.
Downside of using this directive is the queries turn out to be much more verbose and the need to repeat the variables at multiple places. But as explained here, it is an inherent part of GraphQL type safety.
Top comments (3)
why I can't use the same concept for mutation
@Ehsan I missed your comment somehow, sorry. I am not sure why it wont work the same for mutation. I will check.
Good job man, you saved me 2 hours of headache :D