GraphQL Tutorial: how to use fields, fragments, and more
Tags: graphql, database, node, tutorial
Published: 2021-01-18 19:09:54

Data query and manipulation are experiencing a historic rise in popularity as modern companies become more reliant on data for day-to-day tasks. Businesses are looking for candidates and technologies that can efficiently generate results despite high volumes of complex data.

GraphQL (Graph Query Language) is the answer many companies are looking for. GraphQL offers tools for complex queries and a less-is-more approach to fetch calls, and it is projected to soon overshadow the REST API format as the query language of tomorrow's job market.

Today, we'll explore the key pieces of GraphQL and show you how to implement each in your own schemas.
 
 
 
**Here’s what we’ll cover today:**
 
* [What is GraphQL?](#what)
* [Graph QL Building Blocks](#building-blocks)
* [Intermediate GraphQL Concepts](#intermediate)
* [What to learn next](#next)


<br>
<h4><b> Upskill in less than 2 hours </b></h4>
 
Learn fullstack GraphQL fast with hands-on practice and projects.
 
<b> [Up and running with Node and GraphQL](https://www.educative.io/courses/up-and-running-with-node-and-graphql) </b>

<br>


<a name="what"></a>
## What is GraphQL
 
GraphQL is a query language for APIs that includes a server-side runtime to execute queries. GraphQL is used alongside open-source back-end server software like Node, Express, or Apollo.

Developed by Facebook in 2012, GraphQL is designed to reduce the number of empty fields and roundabout fetch calls common with the RESTful API formats.

As GraphQL has developed, the philosophy has continued to prioritize reducing the number of steps for any behavior.

REST API stores objects at specific URLs, but GraphQL has a user-created **type** system that acts as a template by defining a set of **fields** that each object of that type will have. You can make many objects of the same type, each with its own values for the defined fields. 

This is similar to the relationship between classes and objects in OOP languages like Java.

Schema:
```js
{
  data: {
    User: {
      name: "Jane Doe"
    }
  }
}
```

Query:
```js
{
  query User {
    name
  }
}
```

At the simplest level, GraphQL is about asking different objects for the value of a specific field. The advantage here is that GraphQL always knows exactly what information you need and returns only the data you want. 

GraphQL allows you to go beyond this simple operation with complex queries that navigate nested objects or modify fetched data using object mutations.

<br>
 
<a name="building-blocks"></a>
 
## GraphQL Building Blocks
The fundamental building blocks of GraphQL are the **schema** and **queries**. 

<br>

 **Schema**: 

The GraphQL [schema](https://www.educative.io/blog/what-are-database-schemas-examples) outlines the categories or `type` that the data can be split into. It also defines what information will be contained in each type. Think of this as a blueprint to display the architecture of your database.

```js
   type Book {
        id: ID
        title: String
        published: Date
        author: Author
    }
    type Author {
        id: ID
        name: String
        book: [Book]
    }
```

<br>

 **Queries**:

Once your data has been mapped out, you need a way to fetch it. GraphQL queries request data by following an input route to the data endpoint. The returned information is called a **payload**. 

   These can be simple requests, like fetching a book name and author by its ID. 
```
    type Query {
        book(id: ID): Book
        author(id: ID): Author
    }
```

Queries can also be complex, like 
asking for the name and bio, and the name of all the books they've written.

```js
    {
        book(id: 100) {
            title
            isbn
            date
            author {
                name
                bio
                books {
                name
                }
            }
        }
    }
```

Below, explore both schema and queries deeper by learning some of the more specific elements of GraphQL.

<br>

### Fields
A `field` is essentially an object-specific attribute that holds a value. The object's parent type defines which fields an object must have. Each field is set at definition to hold certain data types, such as `String` or `Enum`.

Let's take a look at an example:

```js
type User {
   id: String!
   email: String!
   name: String
}
```

Here, we have a type `User` that we'll use as a template to represent individual users. Each object of type `User` will have three fields: `id`, `email`, and `name`. 

Fields can also reference other objects to create hierarchies between different types of objects. For example, we could add a `friends` field to our `User` that contains a list filled with the names of other users. 
```js
type User {
   id: String!
   email: String!
   name: String
"friends": [
        {
          "name": "John Doe"
        },
        {
          "name": "Jane Doe"
        },
        {
          "name": "Guy Manson"
        }
}
```
> The `!` here means that this field cannot hold the value of `null`. In other words, each user must have an `id` and `email`, but `name` is optional.

GraphQL can fetch the entire `friends` list object at once or traverse the object to find a specific piece of data. This function allows you to fetch large amounts of related data/objects in just a single query.

<bR>
 
### Arguments
One of the most useful parts of GraphQL is that you can pass arguments to any field or object within a query. Fields accept arguments similar to functions in other languages, in that arguments have a name and a passed value. The object/field will then use this value wherever the argument's name is referenced. 

In REST API, you can only send the query parameters and the URL segment for the query. GraphQL's approach allows you to skip several queries by passing arguments to anything and receiving the exact information needed in just a single query.

The most common use of arguments is to filter which object you're querying for within a type. For example, we could include the `getUser` field in our `User` type that accepts an `id` argument. Since each user has a specific `id`, this will allow us to easily pull the information about a specific user.

```js
{
  getName(id: "1010") {
    name
  }
}
```

<br>

### Aliases
GraphQL will throw an error if we query the same field with different arguments. Imagine we have our `user` objects and want to filter them by an implemented "subscriptionStatus" argument.

```js
query getUsers {
  user(subscriptionStatus: SUBSCRIBED) {
  id
  email
  name
  }
  user(subscriptionStatus: UNSUBSCRIBED) {
  id
  email
  name
  }
}
```

This would throw an error because the later query on the `users` type will overwrite the previous one.
```
message: "Fields "user" conflict because they have differing arguments. Use different aliases on the fields to fetch both if this was intentional."
```

As the error says, we need to set **aliases** for these queries to fetch both at once. You can think of aliases as nicknames for specific subgroups within a type. 

We'll set alias `subscribers` for user objects with a `subscriptionStatus` of `SUBSCRIBED`:

```js
query getUsers {
  subscribers: user(subscriptionStatus: SUBSCRIBED) {
  id
  email
  name
  }
```


We can use the `subscribers` alias later as a shortcut to query this subgroup of `user` whenever we want. Aliases are an effective way to divide wider types into more specific groups that you'll frequently query together.

<br>


<div style="background-color:#F1F1FF;padding-left: 10px;padding-top:1px;padding-bottom:1px;">

### Keep learning about GraphQL

Widen your skillset with experience in GraphQL and Nodejs. Educative's mini-courses give you the hands-on experience to grow as a developer in less than 2 hours.

<b>[Up and running with Node and GraphQL](https://www.educative.io/courses/up-and-running-with-node-and-graphql)</b>
</div>

<br>

<br>
 
<a name="intermediate"></a>
 

## Intermediate GraphQL Concepts

<br>

### Fragments
In complex applications, you'll likely have several operations that reference the same fields. To shorthand this, GraphQL includes **fragments** that allow you to wrap a set of fields for reuse across your different queries. Fragments are defined for an object type, like `User`, and they can be used in any operation that features those objects.

Below, we'll remake our previous arguments example but this time replace the identical fields with our `AccountInfo` fragment.

Without Fragments:
```js
query getUsers {
     subscribers: user(subscriptionStatus: SUBSCRIBED) {
  id
  email
  name
  }

  nonSubscribers: user(subscriptionStatus: UNSUBSCRIBED) {
  id
  email
  name
  }
```

With Fragments:
```js
query getUsers {
     subscribers: user(subscriptionStatus: SUBSCRIBED) {
  id
  ...AccountInfo

  nonSubscribers: user(subscriptionStatus: UNSUBSCRIBED) {
  id
  ...AccountInfo
  }



fragment AccountInfo on User{
  email
  name
}
```

Both of these code segments accomplish the same behavior. The advantage of fragments is that they simplify our queries for readability and allow us to modularize queries for reuse.


<br>

### Variables
Sometimes we'll want to include the option for dynamic arguments in our queries, such as when making a search bar. GraphQL allows dynamic arguments using **variables**. Variables act as a placeholder that points to a field within a paired JSON file.

To implement a variable, we have to make three changes:
- Replace the static argument with a variable anchor, `$subscriptionStatus: Subscription`
- Declare `$subscriptionStatus` as one of the variables accepted by the query
- Pass `Subscription: value` in a separate variable dictionary file (usually JSON)

Query:
```js
query getUsers ($subscriptionStatus: Subscription) {
    user(subscriptionStatus: $subscriptionStatus) {
  id
  ...AccountInfo
    }
}
```

Variable Dictionary:
``` 
"subscriptionStatus": "SUBSCRIBED"
```

Now we can change which group of users we're analyzing across the entire program by simply changing the value of `subscriptionStatus` in the variables dictionary. 

Variables, therefore, allow your queries to be adaptable and widen the reusability of behaviors.

<br>
 
### Mutations

While queries let you fetch data, **mutations** let you create, update, or delete server-side data. You can think of mutations as the GraphQL equivalent of `POST` from REST API.

To implement a mutation, you need to set the field name and the arguments it will accept. Imagine we're trying to add a mutation that allows us to create more `User` objects. We need to create a mutation query that will accept all the essential information for account creation:

```js
mutation createUser(email: String!, password: String!) {
   createUser(email: $email, password: $password) {
      id
      email
      password
}
```

First, we declare that `createUser` will be a mutation and accept arguments named `email` and `password`. Then in **line 2**, we declare that these arguments will be used to populate the separate `email` and `password` fields below.

Mutations exist on a spectrum between *fine-grained*, meaning it only edits a few specific fields, and *coarse-grained*, which edits entire types.

<bR>

### Directives
Sometimes we only want to fetch a field's value under certain conditions. To do this, we can use **directives**, which tells the server to skip or include a field. Directives always include a conditional statement like `if`, and a boolean variable. 

With this feature, you can skip tricky string manipulations or allow you to implement "show more" buttons on UI readouts. 

The two types of basic directives act as logical switches. Each directive activates if the boolean is true to avoid double negatives; `include` indicates to shows the field when the boolean is `true` and `skip` indicates not to show the field when the boolean is `true`.

- `@include(if: Boolean)` Only include this field in the result if the argument is `true`.
- `@skip(if: Boolean)` Skip this field if the argument is `true`.
Imagine we want to fetch user data but only want to include the email address if a specific setting is ticked.

Query:
```js
{
query getUsers {
User {   
   name
   email @include(if: $showEmail)
  }
}
```

Variable Dictionary:
```js
"showEmail": true
```

<br>
 
<a name="next"></a>
## What to learn next
Now that you've seen all the basic pieces of GraphQL in action, you're ready to explore more advanced concepts like resolvers or combining GraphQL with back-end software. 

API and data manipulation are rising in demand as more businesses adopt data-driven methods. Now is the perfect time to upskill with GraphQL.

Setting up your own GraphQL server with Nodejs is the best way to practice your skills. To help you do that, Educative has created the [**Up and running with Node and GraphQL**](https://www.educative.io/courses/up-and-running-with-node-and-graphql). This mini-course acts as a compact crash course to pivot JavaScript developers to GraphQL API implementations. 

By the end, you'll have hands-on experience launching and manipulating your own GraphQL server.

*Happy learning!*


<br>

### Continue reading about APIs and databases
- [How to use an API: fetch daily images with NASA's Open API](https://www.educative.io/blog/how-to-use-api-nasa-daily-image)
- [What is a Database Query? SQL and NoSQL queries explained](https://www.educative.io/blog/what-is-database-query-sql-nosql)
- [MySQL Workbench Tutorial: complete guide to the RDBMS tool](https://www.educative.io/blog/mysql-workbench-tutorial)