In the beginning stages of a project while the green fields of rich possibility still stretch ahead of you and the future looks rosy, it’s easy to imagine that the simplest solution will perfectly meet your client’s needs.

Let’s say your client’s MMA fansite has taken off. They’re converting their site from server-side rendering to React and you’re tasked with building the API.

The first task is to list the top 50 most popular fighters. No problem, you say, as you roll up your sleeves and put on your REST hat.

One magic incantation later and you’ve got:

GET /fighters?sort=popularity&limit=50

It returns a JSON array of MMA fighters and their vital statistics such as height, weight etc.

Next task is to show the three most recent fights that each fighter took part in, and the results. Hmm, you say, how about:

GET /fighters/1/fights?sort=recent&limit=3

But wait - now your home page is taking 10 seconds to load because you have an N+1 problem. The client has to make 1 query for the fighters and then 50 more queries to get the latest fights for each one.

You’re now forced to make a choice from two unpalatable options:

  1. Include the top three fights nested inside the JSON for each fighter. Solves this particular use case but is hardly reusable or extensible.
  2. Include ALL of the fights nested inside the JSON for each fighter. More generally usable but what if they are Muay Thai fighters and have on the order of 400 fights each? Now your request payload is enormous.

After some agonising and sweating you grimly grab hold of your REST stick and choose the first option.

GET /fighters?limit=50&with_recent_fights=3

But wait - now the client wants to show an individual fighter’s page with all of his fights, and also list the top 10 most popular fighters in the sidebar.

There’s no way around it. Unless you create a specialized endpoint, the client has to make two requests. One to an endpoint that returns the individual fighter along with his fights, and another one to get the top ten fighters.

So you opt to create a specialized endpoint. This takes more development time and your frontend dev is left idly waiting around for you to get it finished.

Wouldn’t it be easier if the client could make one request per page specifying exactly what it needs and get that data and only that data all in one hit?

Enter GraphQL

GraphQL allows you to do exactly that. It minimises the need for specialized endpoints and time-costly iterations between backend and frontend developers by giving the client the power to tell the server exactly what it needs.

It’s also self-documenting, so the documentation is always automatically up to date and your frontend dev can see exactly what data he can ask for without having to ask the backend developers or even worse, look at backend source code.

What’s more, it’s type safe - so you can always rely on exactly the right type coming from the backend. This becomes even more useful if you are using a typed language on the frontend like TypeScript, Elm or ReasonML.

All of the use cases are easily accomplished with a simple GraphQL schema. One endpoint, and one request per page load no matter what data you want to show.

What is GraphQL?

GraphQL is a specification for a query language, and a typed schema.

It is language-independent - there are both client and server implementations for many languages including JavaScript, Ruby, Elixir, Java, Haskell and probably a lot more.

It is also agnostic about the storage engine you use, or indeed if you even use one at all.

Here is how we might write the query to fetch our fighters from the example above:

query SideBarFighters {
  fighters(limit: 10, sort: "popularity") {
    fights(limit: 3, sort: "recent") {
query MainFighter {
  fighter(id: 42) {
    fights(sort: "recent") {

The client is able to tell the server at query time exactly what data it wants. The query reflects the schema in structure so it’s easy to see what you will receive back.


There are many articles describing the benefits of using GraphQL instead where you would traditionally use REST. Most boil down to better handling of nested data structures/relations and giving the client the power to choose exactly what it wants in a request allowing you to have one API for multiple clients.

For more information see these articles:

I actually wrote this article a while ago and never got round to publishing it.

I’ve been using GraphQL in production extensively for the past several years now and at this point I’d have to have a very good reason to choose REST over it for a new project.

If you want to learn more about GraphQL, I recommend checking out my talk at Elixir Conf 2018 where I go into a lot more detail about how it works and the problems it solves.