DEV Community

freakomonk
freakomonk

Posted on

Dynamic queries in GraphQL

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

  1. There is a checklist on the UI containing which data elements need to be fetched.
  2. 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)

Collapse
 
ehsansarshar profile image
Ehsan sarshar • Edited

why I can't use the same concept for mutation

Collapse
 
freakomonk profile image
freakomonk

@Ehsan I missed your comment somehow, sorry. I am not sure why it wont work the same for mutation. I will check.

Collapse
 
xhevoibraimi profile image
xhevo

Good job man, you saved me 2 hours of headache :D