Introduction to GraphQL — Variables and Complex Operations
Tags: graphql, webdev, programming, javascript
Published: 2021-01-25 01:41:39

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**

GraphQL is a query language for our API and a server-side runtime for running queries by using a type system for our data.

In this article, we’ll look at more complex GraphQL operations, including passing in variables, directives, mutations, and more.

Variables
=========

In most apps, the arguments for queries need to be dynamic. It wouldn’t be a good idea to pass in dynamic arguments directly to the query string.

Fortunately, GraphQL lets us pass in variables into our operations request.

For example, we can write:

```
query PersonName($id: Int) {  
  person(id: $id) {  
    name  
  }  
}
```

to pass in an `$id` variable into our `person` query.

Then we can pass in variables via an object to make the request:

```
{  
  "id": 1000  
}
```

Then we get something like:

```
{  
  "data": {  
    "person": {  
      "name": "Jane"  
    }  
  }  
}
```

as the response.

Variable definitions
====================

Variable definitions start with the variable name prefixed with a `$`, then the type of the variable.

In the example above, we have `$id` as the variable name and `Int` as the type.

All declared variables must be either a scalar, enums or other input object types.

If we want to pass a complex object into a field, we need to know the input type to match on the server.

Default variables
=================

We can set default values for variables as follows:

```
query PersonName($id: Int = 1) {  
  person(id: $id) {  
    name  
  }  
}
```

In the code above, we added `= 1` after `$id: Int` to set the default value for `$id` to 1.

Directives
==========

We can use directives to dynamically change the structure and shape of our queries using variables.

For example, we can include directives as follows to make our query dynamic:

```
query Person($id: Int, $withFriends: Boolean!) {  
  person(id: $id) {  
    name  
    friends @include(if: $withFriends) {  
      name  
    }  
  }  
}
```

In the code above, we have the `@include(if: $withFriends)` directive to conditionally includes `friends` if `$withFriends` is `true`.

Therefore, if we make the following query with the following variables:

```
{  
  "id": 1000,  
  "withFriends": false  
}
```

Then we may get something like:

```
{  
  "data": {  
    "person": {  
      "name": "Jane"  
    }  
  }  
}
```

as a response.

A directive can be attached to a field or fragment inclusion and can affect the execution of the query in any way the server desires.

The core GraphQL specification includes 2 directives that must be supported by any spec-compliant GraphQL server implementation:

*   `@include(if: Boolean)` — only include this field if the argument if `true`.
*   `@skip(if: Boolean)` — skip this field if the argument is `true`.

It helps us get out of situations where we would have to do string manipulating to add and remove fields in our query.

Mutations
=========

We can use mutations to send requests to change data on the server.

They’re similar to queries, except that it starts with the keyword `mutation` instead.

For example, we can define a mutation as follows:

```
mutation CreatePerson($firstName: String, $lastName: String) {  
  createPerson(firstName: $firstName, lastName: $lastName) {  
    firstName  
    lastName  
  }  
}
```

Then if we make the following query:

```
{  
  "firstName": "Joe",  
  "lastName": "Smith"  
}
```

we may get the following response:

```
{  
  "data": {  
    "createPerson": {  
      "firstName": "Joe",  
      "lastName": "Smith"  
    }  
  }  
}
```

In the response, we return the `firstName` and `lastName` fields as we specified in the request.

A mutation can contain multiple fields like a query. Mutations fields run in series.

This means that if we sent 2 `createPerson` mutations in one request. The first will finish before the second begins.

Inline Fragments
================

We can define interface and union types with GraphQL requests.

To do this, we use inline fragments to access data on the underlying concrete type.

For example, we can write the following query:

```
query Thing($id: Int!) {  
  person(id: $id) {  
    name  
    ... on Person{  
      gender  
    }  
    ... on Robot{  
      memory  
    }  
  }  
}
```

In the query above, the `...on` operator indicates that we include an inline fragment within our query, where `Person` and `Robot` are our fragments.

Named fragments can also be inline fragments since they have a type attached.

Meta fields
===========

We can request a `__typename` field to get the type of data returned in the response.

For example, if we have the following query:

```
{  
  search(text: "an") {  
    __typename  
    ... on Human {  
      name  
    }  
    ... on Robot {  
      name  
    }  
  }  
}
```

Then we may get the following response from the server:

```
{  
  "data": {  
    "search": [  
      {  
        "__typename": "Human",  
        "name": "Hans"  
      },  
      {  
        "__typename": "Robot",  
        "name": "Jane"  
      }  
    ]  
  }  
}
```

Conclusion
==========

We can define mutations to make requests to change data.

To make requests dynamic, we can use variables to include variable data and directives for conditional inclusion of data in our response.

We can also use inline fragments for union types and include the type of data returned in the response by including the `__typename` property.