Build a GraphQL API in under 20 minutes

Tell your back-end exactly what data you want, when you want it.

Scott Domes
Code == Life
8 min readSep 7, 2017

--

GraphQL is exciting.

Why? It’s an innovative way of managing the relationship between client and server, in a way that makes building both sides easier and faster.

Some hail it as the end of REST. Instead of calling individual endpoints to get data—each endpoint tailored to distributing a specific piece of the data— we call a single endpoint and get back all the information we want, structured exactly the way we want it.

In this tutorial, we’ll build a simple Rails and GraphQL API. By the end, you’ll know how to integrate GraphQL into an existing Rails application, and also get glimpse of why the protocol is so exciting.

Let’s get to it.

What We’re Going to Build

GraphQL is all about relationships—picturing your database as literally a graph of related nodes. To match that, let’s create a simple relationship schema.

In fact, we’ll use the best relationship of all: between people and their pets.

Say you have a database with Person models and Pet models. You’re working on the front-end of an application to display each person in the database, along with their pets. But you also want to display the reverse—to show all the pets along with their people.

In the old REST paradigm, you’d need two endpoints to achieve this. We’re going to do it in one.

Here is the JSON data we want to eventually receive.

Call 1, to get people with their pets:

Call 2, to get the pets each with their person:

We’re going to build our Rails app, and then do the GraphQL good stuff.

Setting Up Rails

Open up a terminal in a working directory and run the following commands:

In the above, we create our app (as an API), then create models for people and pets.

If you open up app/models/pet.rb, you’ll see the model already belongs to a person.

Open up app/models/person.rb and we can add the other side of the relationship:

Now we have a relationship between people and pets. Pets belong to people, who have multiple pets.

Before we move to the GraphQL bit, let’s populate our database.

Open up the Rails console with rails c and then run the following commands (with your name, of course):

Installing GraphQL

It’s so easy: in your Gemfile add gem 'graphql' and then run bundle install. (Make sure to exit your Rails console first!)

Then, inside app/, create a types folder. This is where all our GraphQL logic will live.

Schemas & Types

Now we can talk GraphQL.

GraphQL relies on two concepts: schemas and types.

Schemas define what data is available, and what type it is. Types determine the structure of the data (what it looks like).

1 is of the integer type. “Hello” is of the string type. Our Person model will be an object type — a type that has fields. What fields those are depends on how we define our PersonType.

All of the above is pretty abstract, so let’s see what it looks like by creating a PersonType.

Our First Type

Inside types/ create a new file, called person_type.rb, and type the following:

We define our PersonType with a name, a description, and then a list of fields. A field is define by a symbol indicating its name, and then what type that field is.

All looks rather straightforward until we get to the field :pets. Here, we see a pet is of the PetType (which we’ll create in a moment). But in order to tell GraphQL where to get the data for the pet, we have to add a resolve function, which grabs the person’s pets.

What resolve does is get the data from person.pets, and then runs that data through the PetType to structure it.

Speaking of which…

Our Second Type

There’s the other half of the equation.

Here, the :person field will grab the pet.person, and then structure it according to the PersonType. This means we can then access the person’s name, surname, and pet, if we want.

Our Schema and QueryType

Now that we have our Types defined, we need a way to query the data we want.

We need a way to tell our API, “hey, give me all the people and their pets” and “hey, give me all the pets with their owners”.

To do that, we need to do three things:

  1. Define our QueryType (how our query is going to appear).
  2. Define our Schema
  3. Make a route to send the queries to.

After that, we’ll be ready to start testing our API!

Our QueryType

The QueryType is the gateway to our data. It defines how requests can ask for data.

Create a new file in the types/ folder called query_type.rb and define it as so:

We open up two fields to our query, :pets and :people. Those fields will then grab the data from Person.all or Pet.all, and filter it through the PersonType and PetType, respectively.

What does this mean? It means we can structure our query like so:

And the GraphQL will process it in the following steps:

QueryType → :people field → PersonType → :name, :surname, :pets fields → PetType → :name field

It will then organize the data exactly as we have defined it above.

Before we see that in action, though, we have to do a little more housekeeping.

Defining Our Schema

Create a new file in the types/ folder called schema.rb, like so:

Our Schema is defined so that we can make a query against it. Not much exciting here.

Defining Our Query Route

Lastly, we need a way into our API: a query route.

The beauty of GraphQL is that all requests for data go through a single endpoint.

Let’s create that endpoint now. Inside config/routes.rb, add the following line before the end.

When we send a POST request to ‘http://localhost:3001/query’, it’ll call the #query method inside our ApplicationController. Next, we’ll create that method.

(Make sure to delete the protect_from_forgery line if it exists)

When this endpoint is called, we execute it according to our GraphQL Schema, based on the query defined in the request params. Then, we send the response back as JSON.

Okay, let’s see it in action!

Testing Our Query

Install and open Postman, and start up our app with rails server -p 3001.

At the start of this tutorial, we defined two queries as our goal. One was to fetch all the people with their pets, and the second was to fetch all the pets with their people.

Here’s what the two look like in Postman, as the body of our POST request.

Query 1:

Query 2:

In Postman:

Note that you must set the body to RAW, as JSON! Also, Postman complains about the pretty multiline version above, so condense it to a single line like the below:

.

Success!

For our two queries, we get back the following:

We did it! Now we can play around with requesting what data we want. If we only want people with their name:

Or just the owner’s name of each pet:

Or even pets with their name and all their owner’s pets:

These examples are limited by our small dataset, but you can imagine the possibilities with real-life complex models, with dozens of fields and dozens of relationships. All can be managed and traversed with one endpoint.

Welcome to the future!

Call to Action

Learned something from this article? Show your appreciation by hitting those clappin’ hands. Even better, share it with your friends and colleagues. Thanks for reading!

For more, you can follow me on Twitter or check out my personal site:

--

--

Scott Domes
Code == Life

Writer & teacher, currently focused on software (JavaScript, Rails & more). Author of Progressive Web Apps with React.