GraphQL Vs REST - Sovereign Solutions

GraphQL Vs REST

image_pdf

Services:  Enterprise Architecture, Data and Analytics
Industries:
Date:  1-23-2019

Overview

GraphQL is a framework that describes how to ask for and load data from a server to a client. GraphQL lets the client specify exactly what data it needs via a custom query, allows aggregation of data from multiple sources and uses a type system to describe data.  The focus of this posting is to show how GraphQL would compare to the typical REST API approach for applications and illustrate the key differences between the approaches.

THERE ARE Two ways to send data over HTTP.  What’s the difference?

GraphQL often presented as a revolutionary new way to think about APIs when compared to REST. Instead of working with rigid, server-defined endpoints, a consumer can send queries to get all the data of interest in a single request. Although GraphQL can be transformative because it enables frontend and backend teams to collaborate and share data in a more streamlined manner, in practice both approaches involve sending an HTTP request and receiving some result and GraphQL has many elements of the REST model built-in.

What’s the real difference on a technical level? What are the similarities and differences between these two API paradigms?  GraphQL and REST are not so different, but that GraphQL has some small changes that make a big difference when building and consuming APIs.

Let’s identify some properties of an API and discuss how GraphQL and REST handle them.

RESOURCES

The core idea of REST is the resource. Each resource is identified by a URL and are retrieved by sending a GET request to that URL. Most requests would get a JSON response that looks similar to this:

GET /books/1

{
“title”: “Black Hole Blues”,
“author”: {
“firstName”: “Janna”,
“lastName”: “Levin”
}
// … more fields here
}

Note: In the example above, some REST APIs would return “author” as a separate resource.

One thing to note in REST is that the type, or shape, of the resource and the way the resource is retrieved are coupled. This would typically be referred to it as the book endpoint.  GraphQL is quite different in this respect, because in GraphQL these two concepts are completely separate. A sample schema is provided using Book and Author types:

type Book {
id: ID
title: String
published: Date
price: String
author: Author
}

type Author {
id: ID
firstName: String
lastName: String
books: [Book]
}

Note that the code describes the kinds of data available, but the description doesn’t tell anything about how those objects might be fetched by a client. This is a core difference between REST and GraphQL:  the description of a resource is not coupled to the way it is retrieved.

To be able to access a particular book or author, a Query type must be created in the schema:

type Query {
book(id: ID!): Book
author(id: ID!): Author
}

Here is a GraphQL request similar to the REST request above:

GET /graphql?query={ book(id: “1”) { title, author { firstName } } }

{
“title”: “Black Hole Blues”,
“author”: {
“firstName”: “Janna”,
}
}

Upon initial inspection, it is clear there are a few things about GraphQL that are quite different from REST, even though both can be requested via URL and both can return the same shape of JSON response.  First, the URL with a GraphQL query specifies the resource being requested and which fields are needed. Second, rather than the server author deciding that the related Author resource needs to be included, the consumer of the API can determine that for themselves.  Third, and most importantly, the identities of the resources and the concepts of Books and Authors are not coupled to the way those resources are retrieved. A consumer could potentially retrieve the same Book through many different types of queries and with different sets of fields based on the data required by the consumer.

CONCLUSION

Upon initial review, some similarities and differences are already clear:

  • Similarities
    • Both have the idea of a resource, and can specify IDs for those resources.
    • Both can be fetched via an HTTP GET request with a URL.
    • Both can return JSON data in the request.
  • Differences
    • In REST, the endpoint that is called is the identity of that object. In GraphQL, the identity is separate from how it is retrieved.
    • In REST, the shape and size of the resource is determined by the server. In GraphQL, the server declares what resources are available, and the client asks for what it needs at the time.

GraphQL Schema Vs URL ROUTES

An API isn’t useful if it isn’t predictable.  Consuming an API is typically done as part of an application or another API.  The consuming system needs to know what it can call and what it should expect to receive as the result, so that it can operate on that result.  One of the most important parts of an API is the description of what can be accessed. This is discovered when reading API documentation, and with GraphQL introspection and REST API schema systems like Swagger this information can be examined programmatically.

In REST APIs, the API is usually described as a list of endpoints:

GET /books/:id
GET /authors/:id
GET /books/:id/comments
POST /books/:id/comments

 

The shape of the API is linear, meaning there is a predefined list of things that can be accessed. When retrieving or saving data, a consumer must consider which endpoint to call.  In GraphQL, URLs are not used to identify what is available in the API. Instead, a GraphQL schema is used:

type Query {
book(id: ID!): Book
author(id: ID!): Author
}

type Mutation {
addComment(input: AddCommentInput): Comment
}

type Book { … }
type Author { … }
type Comment { … }
input AddCommentInput { … }

 

 

There is an obvious difference when compared to the REST routes for a similar data set. Instead of sending a different HTTP verb to the same URL to differentiate a read versus a write, GraphQL uses a different initial type of Mutation versus Query. In a GraphQL document, the consumer can select which type of operation to send with a keyword:

query { … }
mutation { … }

 

The fields on the Query type match up pretty nicely with the REST routes used above. That’s because this special type is the entry point into the data, so this is the most equivalent concept in GraphQL to an endpoint URL.

The way to get the initial resource from a GraphQL API is similar to REST in that a name and parameters are passed, but the main difference is what can be done from there. In GraphQL, a complex query that retrieves additional data according to relationships defined in the schema can be sent, but in REST this would have to be done via multiple requests, building the related data into the initial response, or including some special parameters in the URL to modify the response.

CONCLUSION

In REST the space of accessible data is described as a linear list of endpoints and in GraphQL it’s a schema with relationships. More specifically:

  • Similarities
    • The list of endpoints in a REST API is similar to the list of fields on the Query and Mutation types in a GraphQL API. They are both the entry points into the data.
    • Both have a way to differentiate if an API request is meant to read data or write it.
  • Differences
    • In GraphQL, a consumer can traverse from the entry point to related data, following relationships defined in the schema, in a single request. In REST, a consumer must call multiple endpoints to fetch related resources.
    • In GraphQL, there’s no difference between the fields on the Query type and the fields on any other type, except that only the query type is accessible at the root of a query. For example, a request can have arguments in any field in a query. In REST, there’s no true concept of a nested URL.
    • In REST, a consumer specifies a write operation by changing the HTTP verb from Get to Post. In GraphQL, a consumer changes a keyword in the query.

RESOLVERS VS ROUTE HANDLERS

When an API is called, it typically executes code on the server that received the request to do a computation, retrieve data from a database or call other APIs. Both REST and GraphQL have standard ways for implementing an API, and it’s useful to compare them to get a sense for how these technologies are different.  For this comparison JavaScript code is used, but this could be implemented in any programming language.

Here’s a Hello World example with Express, a popular API library for Node:

app.get(‘/hello’, function (req, res) {
res.send(‘Hello World!’)
})

 

This creates a /hello endpoint that returns the string “Hello World!”. The lifecycle of an HTTP request in the REST API server consists of the following steps:

  1. The server receives the request and retrieves the HTTP Get verb and URL path.
  2. The API library matches up the verb and path to a function registered by the server code.
  3. The function executes once and returns a result.
  4. The API library serializes the result, adds the appropriate response code and headers, and sends the result to the client.

GraphQL works in a very similar way and the code for the Hello World example is very similar:

const resolvers = {
Query: {
hello: () => {
return ‘Hello world!’;
},
},
};

 

Instead of providing a function for a specific URL, a function is provided that matches a particular field on a type, in this case the hello field on the Query type. In GraphQL, this function that implements a field is called a resolver.

To make a request, a query is required:

query {
hello
}

 

The lifecycle of an HTTP request in the GraphQL server consists of these steps:

  1. The server receives the request and retrieves the GraphQL query.
  2. The query is traversed and for each field the appropriate resolver is called. In this case, there’s only one field, hello, and it’s on the Query type.
  3. The function is called and it returns a result.
  4. The GraphQL library and server attaches that result to a response that matches the shape of the query.

The client gets the following result back:

{ “hello”: “Hello, world!” }

 

Multiple fields can be executed in one request and the same field can be called multiple times at different points in the query.  Here is a more complex example of nested resolvers:

{
Query: {
author: (root, { id }) => find(authors, { id: id }),
},
Author: {
posts: (author) => filter(posts, { authorId: author.id }),
},
}

These resolvers would be able to fulfill a query like this:

query {
author(id: 1) {
firstName
posts {
title
}
}
}

 

Although the set of resolvers is actually flat, they are attached to various types and can be built into nested queries.

Diagram of GraphQL vs REST Request Flow

Request flow for fetching resources with multiple roundtrip REST requests versus one GraphQL request

Conclusion

Both REST and GraphQL APIs provide a means to call functions over a network. Implementing a GraphQL API is similar to building a REST API, although GraphQL has the advantage of calling several related functions in a single roundtrip request.

  • Similarities
    • Endpoints in REST and fields in GraphQL both call functions on the server.
    • Both REST and GraphQL rely on frameworks and libraries to handle the underlying implementation.
  • Differences
    • In REST, each request typically calls exactly one route handler function. In GraphQL, one query can call many resolvers to construct a nested response with multiple resources.
    • In REST, the developer constructs the shape of the response. In GraphQL, the shape of the response is built up by the GraphQL execution library to match the shape of the query.
    • GraphQL is a system for calling many nested endpoints in one request whereas REST allows for only calling a single endpoint.

Real-World Outcome

REST and GraphQL operate with fundamentally similar concepts, but there are several key differences in GraphQL’s favor. GraphQL allows for implementing an API as a set of small resolver functions and supports complex queries that retrieves multiple resources in a single roundtrip. This saves the API implementer from having to create multiple endpoints with specific shapes and enables the API consumer to avoid fetching extra data they don’t need.  REST has some advantages as well.  Although GraphQL tools are maturing quickly, GraphQL results cannot be cached using HTTP caching as easily as REST results.  Additionally, in order for an API platform to fully leverage all the benefits of GraphQL, all relevant APIs must be implemented in or migrated to GraphQL, which may not always be practical.


Talk to our experts now to learn how Sovereign Solutions can help your organization meet its business objectives.

*This content is being provided for informational and educational purposes, and should not be regarded as a specific recommendation for your situation.