Is GraphQL the Future of Web Service APIs?

Since early 2000, REpresentational State Transfer (REST) has been the go to solution for providing web service APIs. By leveraging the existing HTTP verbs, e.g., POST, GET, PUT, and DELETE, it provides a simple mechanism allowing client code, e.g., the a browser web application, to perform Create, Read, Update, and Delete (CRUD) operations on server managed data.

As strictly following REST patterns introduces some common problems; defacto solutions (extending REST) have arisen to work around them. On the other hand, GraphQL (a Facebook open source product) provides an alternate solution for web service APIs that does not suffer from the common problems of REST.

A REST API, a Problem, and a Work Around Solution

This example’s data structure consists of a list of items that have a list of parts, i.e.,

[{
id: 'gcat',
name: 'grumpy cat',
description: 'He is one cranky dude.',
parts: [{
id: 0,
name: 'fur',
}, {
id: 1,
name 'teeth',
}],
}, {
id: 'sdog',
name: 'super dog',
parts: [{
id: 3,
name: 'tail',
}]
}]

The strict (read-only) REST API has the following endpoints:

  • GET: /items
  • GET: /items/:id
  • GET: /parts
  • GET: /parts/:id

The items endpoints return the id, name, and (optional) description. The parts endpoints return the id, name, and related item (actually its id).

note: The API splits the items and parts for performance reasons, e.g., the client code does not need the parts detail when simply listing the items.

For the client code to work with a single item, it first uses the GET: /items/:id followed by a GET /parts. But, herein lies a problem: The list of parts may be large compared to the subset of related parts.

A work around solution is to add an optional parameter to the GET: /parts endpoint, i.e., GET /parts?item=id where id is the related item id.

To see this example in action, build and run:

  • Install Node.js.
  • Download and extract the repository Hello GraphQL.
  • From the extracted folder, run npm install
  • Run the command node rest.js

To use the API, use a browser or a web service testing tool, e.g., Postman, to make the following requests:

  • GET: http://localhost:4000/items/gcat
  • GET: http://localhost:4000/parts?item=gcat

to get the following results:

{
"id": "gcat",
"name": "grumpy cat",
"description": "He is one cranky dude."
}

and

[
{
"id": 0,
"name": "fur",
"itemId": "gcat"
},
{
"id": 1,
"name": "teeth",
"itemId": "gcat"
}
]

A GraphQL API

In the previous example, getting all the details of a single item required two API calls (one for the item and one for the related parts). If the data structure was more complicated (say item had multiple relationships) then we would have to add an additional API call for each relationship. One can see how the REST (with its work around solution) API will have scaling problems as the complexity of the data model grows.

As an alternative, we can implement the same data model using GraphQL.

To build and run (assuming that you built the REST version above):

  • Run the command node graphql.js

One way to test the API is to go to http://localhost:4000/graphql in a browser to start the GraphiQL in-browser IDE for testing GraphQL queries.

Run the following query to get a single item and the related parts.

query {
item(id: "gcat") {
id
name
description
parts {
id
name
}
}
}

One can also use the browser or a web service testing tool to make the following GET request:

http://localhost:4000/graphql?query=query { item(id: "gcat") { id name description parts { id name } } }

Either way the result of the single API call is:

{
"data": {
"item": {
"id": "gcat",
"name": "grumpy cat",
"description": "He is one cranky dude.",
"parts": [
{
"id": 0,
"name": "fur"
},
{
"id": 1,
"name": "teeth"
}
]
}
}
}

Comparison of REST and GraphQL APIs

First, one could improve on our REST implementation to overcome the scaling problems, e.g., could add an additional parameter to the GET: /items/:id call to return the related parts. But, such implementations would be non-standard; thus more challenging to support over the long term.

On the other hand, the GraphQL provides a well documented robust query vocabulary that allows one to return complex data results through a single API call.

Looking at the source code of the REST API, it is a fairly simple (and familiar) implementation.

The source code of the GraphQL API, while also fairly simple, requires one to learn the GraphQL schema syntax and is based on JavaScript classes (both less familiar).

While the robust vocabulary is a benefit of GraphQL, it can be fairly complex (intimidating) at first, e.g., in our simple example we did not use any of the core concepts of: aliases, fragments, variables, operation name, directives, mutations, inline fragments, etc. As a matter of fact, I do not know what all of these are myself.

Bottom Line

The projects that I have been working on have relatively simple data structures with relatively low traffic; thus a couple extra REST API calls have an insignificant impact on performance.

My current thinking is that I will continue with my REST API implementation approach until I hit a point where I am starting to run into performance issues. At that point, rather than trying to implement non-standard solutions to improve on REST, I plan on first trying GraphQL to see if solves the problem (I suspect it would).

Written by

Broad infrastructure, development, and soft-skill background

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store