REST versus GraphQL

rest-vs-graphql-header.png

In this tutorial, we will compare Rest with GraphQL which has cool features and solves most of the problems faced with REST but neither of them is a silver bullet.

Introduction

In this article, we’ll be taking a technical look at REST versus GraphQL, comparing and contrasting the two API specifications.

So you have been building and consuming REST APIs for some time now and recently you started hearing about GraphQL, and how people are saying it’s Rest 2.0. Now you are wondering what’s all the fuss about GraphQL and what makes it different from REST.

Brief Introduction to GraphQL

GraphQL is a declarative data fetching specification and query language for APIs. It was created by Facebook back in 2012 to power their mobile applications. It is meant to provide a common interface between the client and the server for data fetching and manipulations. GraphQL was open sourced by Facebook in 2015.

Similarities Between REST and GraphQL

So what could these two have in common? Well, one obvious thing they have in common is that they are both specifications for building and consuming APIs. Also, REST and GraphQL can both be operated over HTTP, though GraphQL is protocol agnostic.

Differences Between REST and GraphQL

Having seen some of the things REST and GraphQL have in common, let’s now look at their differences and how they handle these differences.

Data fetching
The most significant improvement that GraphQL introduced is data fetching. In a typical REST API, to fetch or retrieve data from a server, we might end up making requests to multiple endpoints. But with GraphQL, we only have one endpoint with which we access data on a server. With a single request, we can get an object and its related objects.

Let’s consider this scenario and see how it can be tackled with REST and then GraphQL: assuming we want to retrieve an author along with the posts he/she has created, and in turn get the comments on each of the posts.

With REST, we might have a /authors/:id endpoint to fetch an author, then another /authors/:id/posts endpoint to fetch the post of that particular author. Lastly, we could have a /authors/:id/posts/:id/comments endpoint that fetches the comments on the posts. As you can see, we need to make requests to three different endpoints in other to accomplish our scenario above.

With GraphQL, we only need to make a request to one endpoint, say /graphql with the following query:

1{
2      author {
3        name
4        posts {
5          title
6          comments {
7            comment
8          }
9        }
10      }
11    }

and we would get a response like:

1{
2      "data": {
3        "author": {
4          "name": "Chimezie Enyinnaya",
5          "posts": [
6            {
7              "title": "How to build a collaborative note app using Laravel",
8              "comments": [
9                {
10                  "comment": "Great article."
11                }
12              ]
13            },
14            {
15              "title": "Event-Driven Laravel Applications",
16              "comments": [
17                {
18                  "comment": "I love event driven applications! :)"
19                }
20              ]
21            }
22          ]
23        }
24      }
25    }

Network Requests
A closer look at the the example above, in the REST implementation, notice we have three different endpoints and to fetch the data for our scenario we will have to make three different requests to the server. In the GraphQL implementation on the other hand we only make a single request to the server. GraphQL reduces network requests by allowing us fetch or retrieve all the data we need in a single query.

Over/Under Fetching
It is easy to fetch more than the data you need with REST, because each endpoint in a REST API has a fixed data structure which it is meant to return whenever it is hit. So, most times we just make do with the data we need and end up ignoring the rest. Also, REST makes it easy to under fetch data hence making us perform additional requests to other endpoints in order to fetch associated data.

With GraphQL that is not the case. Because GraphQL is a declarative data fetching specification and a query language, we only fetch what we need from the server by constructing our query to only include what we need. The query below will only fetch the author’s name, nothing more and nothing less:

1{
2      author {
3        name
4      }
5    }
6
7
8    {
9      "data": {
10        "author": {
11          "name": "Chimezie Enyinnaya"
12        }
13      }
14    }

Error Handling
Error handling in REST is pretty straightforward, we simply check the HTTP headers to get the status of a response. Depending on the HTTP status code ( 404, 503, 500 etc) we get, we can easily tell what the error is and how to go about resolving it. GraphQL on the other hand, when operated over HTTP, we will always get a 200 OK response status. When an error occurs while processing GraphQL queries, the complete error message is sent to the client with the response. Below is a sample of a typical GraphQL error message:

1{
2      "errors": [
3        {
4          "message": "Field \"hello\" must not have a selection since type \"String\" has no subfields.",
5          "locations": [
6            {
7              "line": 2,
8              "column": 9
9            }
10          ]
11        }
12      ]
13    }

Caching
Since HTTP already implements caching, and REST is implemented using HTTP, the client can use HTTP caching to avoid refetching resources. GraphQL has no caching mechanism in place, hence leaving the clients with the responsibility of taking care of caching on their end.

Versioning
Often when consuming third-party REST APIs, we see stuff like v1, v2, v3 etc. which simply indicate the version of the REST API we are using. This leads to code redundancy and less maintainable code. With GraphQL, there is no need for versioning as we can easily add new fields and types to our GraphQL API without impacting existing queries. Also, we can easily mark fields as deprecated and the fields will be excluded from the response gotten from the server.

GraphQL Ecosystem

Let’s now take a moment to look at some libraries, tools and services that will make working with GraphQL awesome.

Clients

  • Relay: powerful GraphQL client developed by Facebook, heavily optimized for performance. It is only available on the web.
  • Apollo Client: community-driven effort to build a powerful, flexible and production ready GraphQL client for all major development platforms. It support various frontend frameworks (React, Angular and Vue) and platforms (iOS, Android).

Server

  • GraphQL.js: the reference implementation of the GraphQL specification, designed for running GraphQL in a Node.js environment.
  • Graphql-tools: a package that enables you to build a production-ready GraphQL.js schema using the GraphQL schema language, rather than using the GraphQL.js type constructors directly. This allows additional support for resolvers, unions, interfaces, custom scalars, modularizing your schema, and more.
  • Apollo-server: a production-ready Node.js GraphQL server library that supports Express, Connect, Hapi, Koa, and other popular Node HTTP servers, with built-in features like persisted queries, batching, and more. Apollo Server works with any GraphQL client, like Apollo, Relay, and more.

For a complete list of GraphQL reference implementations for various languages, check server libraries section on http://graphql.org/code.

Tools

Graphiql: an interactive in-browser IDE for exploring GraphQL.

GraphiQL

Services

Apollo Optics: a service for visualizing, monitoring and scaling your GraphQL services.

Apollo Optics – https://www.apollodata.com/optics

Graphcool: a GraphQL backend for your applications with a powerful web ui for managing your database and stored data. According to their website, it’s “the GraphQL backend for mobile & web developers”. With Graphcool you don’t have to spend time and infrastructure setting up a server on your own. It integrates well with various third party services/APIs. It supports quite a number of technologies(React, React Native, Vue, Angular, iOS, Android) and GraphQL clients(Apollo, Relay).

Graphcool – https://www.graph.cool

Hygraph: a GraphQL based headless content management system. It lets you build a hosted GraphQL backend for your apps and gives you all the tools you need to manage your content.

Hygraph – https://hygraph.com

Conclusion

In summary, GraphQL is the new kid in the block with lot of cool features and it solves most of the problem faced with REST. Neither REST nor GraphQL is a silver bullet, they both have their strengths and weaknesses. Deciding on the one to use as always, depends on the use case.