What’s all the hype about GraphQL?

Wrapping a REST API with GraphQL

3 ways GraphQL can transform your API for better data retrieval

Jonathan

--

There’s been a lot of hype around GraphQL so we decided to jump on board.

Resources to follow along:

Why GraphQL?

  • REST does not give us any schema definition for the data returned by any of our API endpoints. GraphQL was built around strongly typed schemas for each endpoint
  • We have to constantly change the code on the Backend to return exactly what we need on the frontend, i.e we’re constantly over fetching or under fetching fields.
  • We had the classic N+1 problem with REST. We can now make a single request to retrieve the data we need.

Let’s Dive!

Our Pumps endpoint: /pumps

This returns a list of pumps as follows:

There is a ton of information here we don’t need in our mobile app but we get all this data when we make a request to the /pumps endpoint. Wouldn’t it be nice if we can just specify what we needed? GraphQL to the rescue!

GraphQL Basics

A GraphQL service starts by defining a type and fields. Fields also have a type. Let’s convert our Pumps to a type to clarify.

type Pumps { objectId: ID!
name: String
Details: String,
verified: Boolean,
price: Int,
location: String,
country: String,
flyer: Flyer
}
// Omitted some fields for brevity

Here we create a type and name it Pumps. Then we specify fields like name, Details, verified, etc and their types like String, Boolean and Int.

Notice objectId: ID! In GraphQL ID is a type for a unique identifier (it is a string). The exclamation point means it cannot be null. Lastly, we see flyer: Flyer. Flyer is our own type that we must define so let’s do that next.

type Flyer { name: String
url: String
}

Awesome! In GraphQL we can define our own types as we did here with Flyer.

Defining the Entry Point for Our GraphQL API

Now we need to provide a Query type. GraphQL has root types and Query is one root type used to specify the entry point for every GraphQL query.

type Query { pumps: [Pumps]}

This now sets the entry point for our query as pumps and we set the type to [Pumps]. The square brackets denote a list so our query is expected to return a list of Pumps.

To invoke this endpoint we structure a query as follows:

query {
pumps {
objectId
name
views
}
}

The above query will perform a query on pumps and return objectId name and views for each object. Notice we are only specifying 3 fields in our query, GraphQL will only return these fields to us. At this point you might be wondering, where does the data come from? We’ll discuss this next

Fetching Data with Resolvers

Each field of a GraphQL query is backed by a function called a resolver. The resolver function, to be implemented by the developer, is responsible for fetching the data for a Query field. In our example we have a pumps field on our Query type. Let’s implement a resolver for this.

const resolver = {
Query: {
pumps: () => {
return fetch('https://devapi.wheredpump.com/pumps').then(res => res.json());
} }}

When a query is executed on the pumps field this resolver is called. The resolver can fetch data from any database, a REST API as we have done here or even another GraphQL server. Now we’ll bring all our skills together and setup a server.

Setting up the server

Create a directory calledGraphQL_Server or any name you prefer and cd into it.

Next run npm init -y. This will create a package.json file for us.

In your current directory run npm i graphql-yoga node-fetch

Create a file and name it schema.graphql Copy and paste the following into that file:

type Query { pumps: [Pumps]}type Pumps { objectId: ID!
name: String
Details: String,
verified: Boolean,
price: Int,
location: String,
country: String,
flyer: Flyer
}type Flyer { name: String
url: String
}

Create a file and name it index.js copy and paste the following into that file:

Let’s walk through this code.

Lines 1–2:

Here we import GraphQLServer from graphql-yoga, this is to setup our GraphQL server and fetch from node-fetch. Node-fetch allows us to use the browsers fetch API.

Line 4:

We are creating a variable for our base url for our fetch request.

Lines 6–15:

This is our resolver from earlier. It tells GraphQL where to grab the data when the pumps field on the Query type is executed. i.e Our REST API endpoint https://devapi.wheredpump.com/pumps

Lines 17–20:

Here we create a new GraphQL Server and pass in an object with two keys as the parameter:

  • typeDefs — which tells the server where to find the schema. Here we provide the path to our schema.graphql file.
  • resolvers — which tells the server where to get the resolvers. We pass in our resolvers object from earlier.

We then save the result of GraphQLServer to a const called server.

Line 23:

We call start on the server object and pass in console.log statement so we get some output in the command line that our server is running.

Now all that’s left to do is to run node index.js in your current directory (GraphQL_Server) and visit http://localhost:4000 in your browser. If you followed everything correctly you should see this in your browser:

Hooray! We’ve wrapped our pumps endpoint with GraphQL. One major advantage for us we didn’t show here is how we solved the N+1 request problem. With our Rest API we first make a request to retrieve pumps then for each pump we make a request to get its location.

With GraphQL we are now able to make a single request like this:

To read more about GraphQL visit this link: How to GraphQL

Happy Coding!

--

--

Jonathan

Entrepreneur — Product Lead — Developer || Sharing my experiences & memes.