GraphQL vs REST

Update: New to GraphQL? Check out What is GraphQL? before jumping into these details...


REST is an architectural approach to creating web services. GraphQL is a query language for designing APIs. Both are used to create web services allowing clients to communicate with remote servers over HTTP.

While REST has been widely accepted as the "de facto" for developing stateless independent microservices, GraphQL is the new kid on the block for rapid API development.

In this article, we'll take a look at both REST and GraphQL. We'll briefly explain how each works and compare the pros and cons to using REST vs GraphQL in developing your web service.

What is REST?

REST stands for Representational State Transfer. REST isn't a library but rather an architectural "way of doing things". Web services are considered RESTful when their implementation adheres to REST principles.

A core concept behind REST is the idea of resources. A resource represents a piece of data you want to retrieve from the server. If your web app is a blog then resources may include posts, comments, users, etc.

Each resource is identified by a URL. You fetch a given resource by sending a HTTP request that may look something like this:

/users/<id>/posts

The server processes your request and returns something like this:

{
  "posts": [
    {
      "title":"My latest post",
      "author":"Sam",
      "views":33
    },
    {
      "title":"My other post",
      "author":"Sam",
      "views":14
    },
    {
      "title":"My first post",
      "author":"Sam",
      "views":53
    }
  ]
}

For a user with a given <id>, the service returns a JSON object with an array of post objects.

What is GraphQL?

Unlike REST, GraphQL is an actual application query language for making HTTP requests that return specified resources. While GraphQL ultimately uses the same HTTP protocol to retrieve information from the server, it leverages a type system defined in a schema. This schema dictates the types of queries that can be run and the data they return.

Unlike REST, GraphQL produces a single API endpoint for communicating with the server.

Let's see how GraphQL would implement the same REST call from the previous example:

query {
  User(id: <id>) {
    posts {
      title,
      author,
      views
    }
  }
}

The server processes the request and returns:

{
  "posts": [
    {
      "title":"My latest post",
      "author":"Sam",
      "views":33
    },
    {
      "title":"My other post",
      "author":"Sam",
      "views":14
    },
    {
      "title":"My first post",
      "author":"Sam",
      "views":53
    }
  ]
}

Notice how the exact same JSON response is returned using GraphQL....

So whats the point?

From the examples, it looks like both GraphQL and REST produce the same result. The GraphQL query seems a bit more verbose than a simple GET request, but both ultimately use the same protocol to return the same thing. So what's the big deal?

Overfetching and underfetching data

One of the main reasons why GraphQL is preferred to REST is the precision with which data is retrieved from the server. While our basic /users/<id>/posts endpoint gave us the data we needed, it may have given us more than we asked for. For example, what if we only wanted the title returned for each post?

This is known as "overfetching" since we got back more than we asked for. Specifically, we got back the author and views along with the title.

Another scenario could be that you need more information about each post. In addition to views, authors, and titles you may also want the number of likes for a given post, etc. This is considered "underfetching" and results in additional requests needed for each post object being returned.

You may be thinking....so what? After all, you could modify the REST endpoint to accept parameters for each field you want returned. You could even filter at the database level or create a new endpoint all together.

And you aren't wrong. But this would require more development work and more coordination across different teams.

Alternatively, with GraphQL we could simply modify our original query to address the "overfetching" problem:

query {
  User(id: <id>) {
    posts {
      title
    }
  }
}

or the "underfetching" problem:

query {
  User(id: <id>) {
    posts {
      title,
      author,
      views,
      followers
    }
  }
}

Notice how in both cases we simply add or subtract fields that we want returned. Remember GraphQL uses the same API endpoint for every query...so no need to bug the API team.

One request to rule them all...

This example clearly illustrates the benefits of using GraphQL over REST. By specifying a clearly designed schema with the data types and queries available, GraphQL implements a more contract-driven approach to communicating with the server.

This better isolates the front end from the back end and allows for more rapid API development as quickly evolving UIs can retrieve the exact information they need.

GraphQL vs REST: Pros and Cons

So should you forget about REST completely? Not at all. It's important to remember that REST remains one of the most popular approaches to microservice architecture. Deciding between GraphQL vs REST depends on how you emphasize the pros and cons of each.

REST pros:

  • widely accepted- REST has been around since 2000 and remains one of the most popular approaches to implementing web services today.
  • reusable - using REST, you can more easily develop independent microservices that work independently of one another. Microservices are (ideally) fully decoupled from clients allowing for them to be accessed by multiple applications.
  • caching - REST inherently supports caching much better than GraphQL. This makes for better performance out of the box.

REST cons

  • excessive round trips - more endpoints requires more requests. We saw how the problem of underfetching can lead to excessive requests over the network.
  • versioning - to avoid breaking changes, REST APIs must implement versioning to ensure production services continue working even when updates are made. This can get messy as more and more versions of your API are released.
  • overfetching - downloading unnecessary data
  • underfetching - not retrieving enough data, resulting in additional requests
  • coordination efforts - it's more difficult to develop front ends independently of back ends since new requirements require new endpoints (or modification of existing endpoints).

GraphQL pros

  • schema - by defining a schema with types of data and queries, GraphQL creates a contract between the client and the server making the data available to the client more obvious. Front end developers don't need to concern themselves with back end.
  • easy to get started - you don't have to be an expert with web service architecture to start producing / consuming GraphQL.
  • precision - you can retrieve exactly the data you're looking for without additional endpoints or modification of those endpoints. GraphQL more efficiently addresses the overfetching/underfetching problem.

GraphQL cons

  • scalability issues - GraphQL is easy to get started with, but can become more of a performance issue as complex queries surface and grow.
  • schema limitations - With GraphQL, you're stuck with the schema that's defined. This can cause headaches when you want more in-depth responses than provided.
  • still fairly new - GraphQL is still considered the new kid on the block. There are only a few select clients that implement it well (Apollo, Relay, and Lokka among the most popular GraphQL clients).

Conclusion

While arguing the pros and cons of GraphQL vs REST can be a never ending conversation, it's important to remember that both achieve the same end result. Both invovle sending HTTP requests and receiving data from a server. Both have the idea of resources and can specify IDs for those resources. Both can return JSON responses.

Answering the question as to which is better for your web service really depends on the dynamic between different dev teams in your organization. If you already follow a microservice architecture, then dropping REST to play with GraphQL may not be the best idea. However if your team emphasizes rapid API development driven by the front end, then GraphQL may be the best fit for you.

Your thoughts?