Our Product Design Process book is out now!

ORDER NOW

GraphQL vs REST: which one is better? (2020)

This post was originally posted in May 2019 and updated in March 2020.

When you need to build an API, your mind will likely jump to REST, the de facto standard for API creation. However, this is changing with the increase of GraphQL popularity.

Not everyone fully understands yet what GraphQL is all about, or why it's being declared as the successor of REST. That's exactly what I'll clear up in this article. Here I'll show off GraphQL's main features and the advantages that it has over REST, highlighting a few points in which both differ.

The goal is to provide a brief explanation to anyone who still hasn't got to know GraphQL, clarify exactly what it does better than REST, for those who are still skeptic about this technology and in which cases we should use GraphQL or REST.

Let's start with the very basics.

What is GraphQL

GraphQL is a query language for APIs that enables declarative data fetching in order to give the client the power to specify exactly the data that is needed from the API. It makes easier to evolve APIs over time.

Now that we know what GraphQL is, I want to clarify what it is not, as I feel that there's still some confusion about it.

Firstly, it doesn't have anything to do with databases. It isn't an alternative to SQL or a brand new ORM.

Secondly, it isn't a REST replacement, but an alternative. You don't have to pick between one and the other, they can happily co-exist in the same project.

Last but not least, GraphQL isn't complicated or scary. It's quite easy to understand its declarative nature and exactly how it's possible to take the best from it.

Who created GraphQL

GraphQL was developed internally by Facebook in 2012 before being open sourced in 2015 with his stable version released just on June 2018. On 7 November 2018, the GraphQL project was moved from Facebook to the newly-established GraphQL Foundation, hosted by the non-profit Linux Foundation.
Lee Byron, GraphQL's creator, aims to to make GraphQL omnipresent across web platforms.

Which companies use GraphQL

GraphQL is being used by teams off all sizes, in many different environments and languages. The main companies that are using GraphQL are Facebook, Github, Pinterest and Shopify.

GraphQL in context

Before moving on to the comparison with REST, I'll go through a simple GraphQL query where we can fetch a user as well as his or her name and age:

query {
  user {
    name
    age
  }
}

And the JSON response we'll get from it:

{
  "user": {
    "name": "Johnathan Joestar",
    "age": 27
   }
}

As I stated previously, GraphQL's declarative nature makes it incredibly easy to understand what's going on at all times, as we are basically writing JSON objects without the values.

What is REST

REST (Representational state transfer) is a software architectural style that defines a set of constraints which make any web service – a true RESTful API. The REST constraints are:

Client-server architecture

Client-server architecture means that the user-interface concerns should be separated from the data storage concerns to improve the user interfaces portability across multiple platforms.

Stateless

A stateless server does not persist any information about the user who uses the API. This means that the server does not remember if the user is sending is first request or not.

Cacheability

REST API responses must define themselves as cachable or non-cachable to prevent clients from providing any inappropriate data that can be used on future requests.

Layered system

A Layered system means that if a proxy or load balancer is placed between client and server, the connections between them shouldn't be affected and the client didn't know if he's connected to the end server or not.

Uniform interface

A Uniform interface suggests that should be an uniform way of interacting with a given server despite of device or application type (website, mobile app). The main guideline is that each individual resources has to be identified on requests.

Who created it

REST was defined by Roy Fielding, a computer scientist, that presented the REST principles in his PhD dissertation in 2000.

Why was GraphQL created if there's already REST

There are two main reasons why companies such as Facebook, Netflix and Coursera started developing alternatives to REST:

1. In the early 2010s there was a boom in mobile usage, which led to some issues with low-powered devices and sloppy networks. REST isn't optimal to deal with those problems;

2. As mobile usage increased, so did the number of different front-end frameworks and platforms that run client applications. Given REST's inflexibility, it was harder to develop a single API that could fit the requirements of every client.

If we go even further, we realize that the main reason why an alternative solution was identified was because most of the data used in modern web and mobile applications has a graph shape. For instance, newspieces have comments, and those comments may have features such as likes or spam flags, which are created or reported by users. This example describes how a graph looks like.

Consequently, Facebook started developing GraphQL. At the same time, Netflix and Coursera were also working on alternatives themselves. After Facebook open-sourced GraphQL, Coursera dropped their efforts and adopted the new tech. Netflix, however, continued developing their own REST alternative and later open sourced Falcor.

Why GraphQL is better than REST

In this section I'll go point by point through a practical example, comparing REST to GraphQL in order to demonstrate the flexibility of Facebook's query language.

Imagine that you have a blog, and you want the front page to show all the latest posts. In order to achieve this, you need to fetch the posts, so you will probably do something like this:

GET /api/posts

[
  {
    "title": "Cooler post",
    "subtitle": "...",
    "date": "07/05/2019"
  },
  {
    "title": "Cool post",
    "subtitle": "...",
    "date": "06/05/2019"
  }
]

But what if you want to see the author as well? You have three options to achieve this:

  • Fetch the authors from another resource:
GET /api/post/:id

{
  "post": {
    ...,
    "author": {
      "name": "Dio Brando"
    }
  }
}
  • Modify the resource to also return the author:
GET /api/posts

[
  {
    ...,
    "author": {
      "name": "Dio Brando"
    }
  },
  {
    ...,
    "author": {
      "name": "Johnathan Joestar"
    }
  }
]
  • Create a new resource that returns the posts with the author:
GET /api/postsWithAuthor

[
  {
    ...,
    "author": {
      "name": "Dio Brando"
    }
  },
  {
    ...,
    "author": {
      "name": "Johnathan Joestar"
    }
  }
]

Each of these approaches will create a problem of its own, so let's have a look at them one by one to see how GraphQL is able to solve the following problems.

Under-fetching

With the first approach – fetching the authors from another resource – you'll end up with two server requests instead of one, and as you continue to scale, you may have even more requests to different endpoints in order to fetch all the needed data.

With GraphQL, this wouldn't happen. You would only have one request, and you wouldn't have to make multiple round trips to the server, as seen below:

query {
  posts {
    title
    subtitle
    date
    author {
      name
    }
  }
}

Over-fetching

Looking at the second approach – modifying the resource to also return the author – you can see that it solved the problem pretty nicely. However, changing a resource may have a secondary effect elsewhere on your application. More precisely, over-fetching.

Let's go back to your blog, but this time you also have a sidebar showing off the top monthly posts with their titles, subtitles and date, that is using the resource /api/posts. Since you modified the resource, now it also shows the author with it. However, we don't need it for the sidebar.

While this may not look like a problem, for users on limited data plans, having a website fetch useless data isn't ideal. Since GraphQL allows the client to only fetch the needed data, this problem wouldn't exist:

query {
  posts {
    title
    subtitle
    date
  }
}

Slow front-end development

Lastly, let's have a look at the last approach – creating a new resource that returns the posts with the author – since it's a common pattern to structure the endpoints according to the views in your project.

While this may solve problems such as the one described above, it also slows down the front-end development, since each specific view needs its specific endpoint. If at any point a view needs new data, the development has to slow down until the endpoint is updated.

Again, since GraphQL gives power to the client to fetch the needed data only, nothing slows down, as it's very simple to just add a new field to a query.

You would get from this:

query {
  posts {
    title
    subtitle
    date
  }
}

To this:

query {
  posts {
    title
    subtitle
    date
    author {
      name
    }
  }
}

GraphQL vs REST comparison

Let's just do a quick recap regarding the differences between REST and GraphQL:

  • GraphQL solves both over-fetching and under-fetching issues by allowing the client to request only the needed data;
  • Since the client now has more freedom in the fetched data, development is much faster with GraphQL than what it would be with REST.

What is GraphQL good for

Nowadays almost every business is aiming to build mobile cross-platform applications because the customer interaction with the product increases significantly if they are able to access it via their phones. When you use a mobile app you expect them to be responsive and with low latency. By using GraphQL you will be able to achieve this goals in a really easy way. It helps the client to just fetch the amount of data needed to render a specific view.

What is REST good for

Until now I imagine that we share the same opinion that GraphQL is awesome, but that's not true. There are still some missing elements to make it perfect. If you aim to have one of the next points in your project, you should consider the usage of REST.

Non-existent HTTP caching mechanism

Nowadays every browser provides an implementation of an HTTP cache to easily avoid refetching resources and to identify if two resources are the same. When using GraphQL there's no way to get a globally unique identifier for a given object because we use the same URL for all the requests. To have cache on GraphQL you have to setup your own cache.

Monitoring and Error Reporting

When using REST you can build a monitoring system based on API responses. On GraphQL you don't have that, because it always return 200 OK status response. A typical GraphQL error looks like this:

HTTP 200 OK

{
    errors: [
        {
            message: 'Something when wrong'
        }
    ]
}

Looking on this response you can see that is very difficult to handle and monitoring different error scenarios.

Resource Attacks

As you now know, with GraphQL you can query exactly what you want whenever you want, but we should be aware that this leads to complex security implications. If a malicious actor tries to submit an expensive nested query to overload your server or database and your server doesn't have the right protections, you will be vulnerable to DDoS (Denial-of-service attack) attacks.

GraphQL's features overview

Now that we know how it stacks up against REST, let's talk about some of the features that are unique to GraphQL.

Schema and Type System

GraphQL uses its own type system to define the schema of an API, with its syntax called Schema Definition Language (SDL). The schema serves as a contract between the server and the client to define how a client can access the data.

Once the schema is defined, the front-end and back-end teams can work independently, as the front-end can be easily tested with mock data. The front-end can also get useful information from the schema, such as its types, queries and mutations using GraphiQL or introspection. The GraphQL's schema also provides type safety, which is a plus for the front-end and back-end development, as it catches type errors early.

A schema example:

type User {
  name: String!
  age: Int
  posts: [Post!]!
}

type Post {
  title: String!
  subtitle: String!
  body: String!
  date: String!
  author: User!
}

type Query {
  users: [User!]!
  user(name: String!): User!
  posts: [Post!]!
  post(title: String!): Post!
}

type Mutation {
  createUser(name: String!, age: Int): User!
  createPost(title: String!, subtitle: String!, body: String!): Post!
}

GraphQL IDE

GraphQL IDE is one of the most useful features of GraphQL development. It takes advantage of its self-documenting nature to make development a breeze.

Using GraphiQL or GraphQL Playground, you can just inspect your schema and even run queries and mutations to test out your API.

GraphQL Playground

Wrap up

GraphQL provides a smooth and fast development environment with its declarative and flexible nature, offering many improvements over REST.

It already has a large community and a vibrant ecosystem, and was already implemented in several popular languages, such as JavaScript, Go and Java.

While this post only dipped the toes into the ocean that is GraphQL, its website has a plethora of information and is an amazing place to learn and start using GraphQL.

If you are aiming to develop an API to be used on a mobile application you should have GraphQL as first option because bandwidth usage matters. If your application requires a robust API, with caching and a monitoring system you should go with REST.

With all this being said, it's not a perfect technology, and it still has a couple of drawbacks when compared with REST. But considering how young it is, the future looks incredibly bright for GraphQL.

At Imaginary Cloud, we simplify complex systems, delivering interfaces that users love. If you’ve enjoyed this article, you will certainly enjoy our newsletter, which may be subscribed below. Take this chance to also check our latest work and, if there is any project that you think we can help with, feel free to reach us. We look forward to hearing from you!