Exploring GraphQL API
Tags: graphql, node, express, json
Published: 2018-03-25 18:48:24

---
title: Exploring GraphQL API
published: true
description: 
tags: graphql, node, express, json
---

In this tutorial I'm going to go through what I have learned about GraphQL. Other tutorials will follow that will build upon the foundations covered here. From its homepage we learn

> GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more

We'll use Express as the web server then hook GraphQL into it and let it serve as the API

As previously [covered](https://dev.to/aurelkurtula/creating-a-basic-website-with-expressjs-j92) express is a lightweight web framework which takes requests from the client and sends appropriate responses back to the browser. 

We can now hook GraphQL to express (as a middleware) and allow GraphQL to take over any requests made to GraphQL. 

## Let's start 

Before doing anything else lets start by downloading the required packages

    npm install --save graphql express express-graphql

Whilst `graphql` and `express` are expected, `express-graphql` is the glue that connects express and GraphQL together. 

In `server.js` we add the following code. 


```javascript
import express from 'express';
import expressGraphQL from 'express-graphql';
const app = express()
app.use('/graphql', expressGraphQL({
    graphiql: true
}))
app.listen(4000, () => {
  console.log('http://localhost:4000')
}) 
```

Normally if we used express alone, it would examine the incoming client request and send a response. However with the above setup Express is setup so that when a request to `/graphql` is made instead of responding Express hands the request over to GraphQL. 

As it can be seen, `express-graphql`, which I named `expressGraphQL`, works as an Express middleware. 

Now all that's left to do is run the server (`npm start`) and navigate to `http://localhost:4000/graphql`. On the page we should see an error message:

```json
{
    "errors": [
        {
            "message": "GraphQL middleware options must contain a schema."
        }
    ]
}
```

Let's fix that by providing a schema to GraphQL

```
import schema from './schema/schema';
const app = express()
app.use('/graphql', expressGraphQL({
    schema,
    graphiql: true
})
```

Now, when navigating to `/graphql` we get a different error but at least we see the GraphiQL interface

![](https://thepracticaldev.s3.amazonaws.com/i/pn1msbj91l1okhmd7hio.png)

## Working with the schema

The schema file is used to specify exactly what the data looks like, and respond with an object. We'll start by responding with this data: 

    { 
        id: 1, 
        firstName: 'Tierney', 
        lastName: 'Sutton',
        age: 54
    }

Pretty simple, when users perform a GraphQL query they are going to get that single artist information.

In the schema file we first need to describe the properties of the data and then actualy respond with the data matching the described properties. 

Let's do that first, 

```
import {
    GraphQLObjectType,
    GraphQLString,
    GraphQLInt
 } from 'graphql';

const ArtistType = new GraphQLObjectType({
    name: 'Artist',
    fields:{
        id: {type: GraphQLString},
        firstName: {type: GraphQLString},
        lastName: {type: GraphQLString}, 
        age: {type: GraphQLInt},
    }
})
```

There we specified an `Artist` type which has few fields and each field requires to be of a specific type. Each type is available from the `graphql` package we already installed, so when using each type do not forget to import it at the top.

## Root Query

A root query is the entry point to GraphQL, it is the thing that fires first and in turn exposes other resources. In our case the root query will expose the `ArtistType`. 

```
const RootQuery = new GraphQLObjectType({
    name: "RootQueryType",
    fields: {
        artist: {
            type: ArtistType,
            resolve() {
                return { 
                    id: 1, 
                    firstName: 'Tierney', 
                    lastName: 'Sutton',
                    age: 54,
                    description: 'this will not show'
                }
            }
        }
    }
});  
```

It's still an instance of `GraphQLObjectType` it still has a name an fields. It can be very complex, something that we might explore in later tutorials but in this case it's very simple. 

Imagine a user comes to our application and asks for `artists`, in that case we will return the object that we already specified - the `ArtistType` object. 

The `resolve` is a function which actually populates the object properties with data. The `resolve` is a node/js function, hence we would fetch data from other APIs or retrieve data from databases and filter it to accommodate the `ArtistType` object. But above I ignored all that and simply hard coded an object that has, amongst other things, the properties required by the `ArtistType`.


## Fetching data instead of hard coding it 

I hope the above example make the use of the `resolve` method very clear, but a more realistic use would be this 

```
const RootQuery = new GraphQLObjectType({
    name: "RootQueryType",
    fields: {
        artist: {
            type: ArtistType,
            resolve() {
                return axios.get(`https://gist.githubusercontent.com/aurelkurtula/0774efc9bf0d126a9d306964332f55b0/raw/8db0d128ba00ee69c298c0dc3f19265d1fcdefe7/artist.json`)
                .then(res => res.data)
            }
        }
    }
});
```

If you visit the [contents we are fetching](https://gist.githubusercontent.com/aurelkurtula/0774efc9bf0d126a9d306964332f55b0/raw/7fe6f38bddaca3496743b8fd0d00eddb1e83210b/artist.json), you'll see that the JSON data being fetched through axios has more content than we need. But the usefulness of GraphQL is exactly this, organising external data in a way that can easily be used

Finally we need to export the `RootQuery`

```
export default new GraphQLSchema({
    query: RootQuery
});
```

And that's it. 

Now let's go to the browser `http://localhost:4000/graphql` and test out the query.

![](https://thepracticaldev.s3.amazonaws.com/i/3podva0z8zd2h5ndshpf.png)

All we would need to do is open an empty object (to access the contents of the root query), then "go into" `artists`, then "grab" the properties made available by the `ArtistType`

```
{
  artist{
    lastName
    firstName
    age 
  }
}
```

Note how if we only wanted their first name we would simply omit `lastName`, and `age`