GraphQL vs. REST API Architecture - Which Should You Use for Your API?
Since the GraphQL specification was open sourced by Facebook in 2015, it has rapidly gained popularity in front-end web development. Why the sudden booming popularity of this new technology, and what advantages does GraphQL provide over traditional REST APIs? In this blog, we will discuss the design principles of GraphQL, compare requests in GraphQL with the same requests in REST, and dive into the benefits of GraphQL over other architectures.
In order to understand the benefits of GraphQL as an API architecture, we’ll need to discuss the role of an API in a client-server structure. An API, or Application Programming Interface, is an intermediary that allows a server to receive structured requests for data from a client, and send a structured response for the requested data. There are a variety of ways to design API architectures. Let’s examine the important underlying design principles that make GraphQL a great fit for modern web apps.
Design Principles of a GraphQL Server
There are 5 design principles outlined in the GraphQL specification that make it a well-crafted solution for modern front-end development. Let’s examine the design principles of GraphQL, considering the Facebook news feed as our use case.
- Queries are structured hierarchically, with tiered and nested fields in a format that matches query to response data 1-to-1. Queries and responses are shaped like trees, with the possibility of querying additional nested fields for each item. In Facebook’s news feed, this structure allows for a single query to return a list of posts, comments on each specific post, then likes for each of those comments.
- The structure is product-centric, focusing on how the frontend wants to receive data, and building the runtime necessary to deliver. This allows for Facebook’s news feed to make one request to the backend for all the data that it needs, then let the server do the heavy lifting of fetching data from different endpoints using GraphQL’s specification
- It uses an application-specific type system which enables developers to ensure that queries use valid types and are syntactically correct before execution. For example, the GraphQL schema for the news feed would require that a field “user” must contain a string, but “likes” must contain a number. If a query attempts to add a different type of input, GraphQL will throw an error before the query is executed.
- GraphQL queries are specified client-side, so the client knows in exactly what format it will receive data. This means that a request from Facebook’s news feed for post data containing a user’s name, comments, and likes could be structured in one object if that’s the format the frontend requested, as opposed to multiple separate pieces of data as with other architectures.
- Server structure with GraphQL must be introspective, or queryable by GraphQL itself. This enables powerful developer tools like GraphiQL or GraphQL playground, both of which would allow Facebook developers to see exactly what queries and fields are available for them to use in their server.
To discuss the shift to GraphQL and how these design principles provide benefits that impact development, we’ll first dive into traditional REST API architecture and see where this architecture may fall short.
Traditional RESTful Architecture
Structure of requests and responses from client to server with REST architecture.
The design paradigm of a REST architecture centers on assigning a relationship between an HTTP request's method (GET, POST, PUT, PATCH, DELETE) and URL endpoint. In REST architecture, each combination of method and endpoint evaluates to distinct, encapsulated functionality. If a client needs data that is not provided by a particular endpoint / method, additional request(s) may be required. The format of data returned from a REST request is dependent on the endpoint-there is no guarantee that this data will be formatted in the way the frontend needs to consume it. In order to use data from a response in a different format than is returned from an endpoint by default, data parsing and manipulation must be written client-side.
Next, let’s take a look at how the GraphQL specification differs from REST, and the benefits that make this new architecture a uniquely-suited solution to solve modern problems of data delivery between client and server.
GraphQL Architecture
With GraphQL, clients are able to reach many different types of data storage with a single endpoint. Source: howtographql.com
Like RESTful APIs, GraphQL APIs are designed to handle HTTP requests and provide responses to those requests. However, that’s where the similarities end. Where REST APIs are built on the connection between a request method and an endpoint, GraphQL APIs are designed to use only one endpoint that is always queried with a POST request, usually to the URL yourdomain.com/graphql.
After the GraphQL endpoint is reached, the burden of client-side requests is handled entirely within the body of the request. This request body must adhere to the GraphQL specification, and the API must have server-side logic in place to handle these requests and provide the appropriate response. This provides a smoother client-side experience than RESTful APIs, which may require the client to make multiple requests for multiple pieces of data, and manipulate the data once it is returned. To clarify how GraphQL accomplishes this, let’s break down the structure of a GraphQL server.
Structure of a GraphQL Server
Server-side logic to enable GraphQL logic consists of Documents with defined server capabilities. These Documents contain Executables and Type System definitions. Type system definitions, as the name implies, define the accepted types and formats inputs and results for each field of data. Executables contain a list of possible operations to be handled, which consist of operation types (query, mutation or subscription), a name for the operation, fields to be queried or written, and a selection set which defines exactly what data will be returned from the operation. Selection sets provide the biggest value add to GraphQL - they allow the client to query a specific set of data and receive a response containing exactly the information that was requested: nothing more, nothing less.
For more information on the structure and syntax of the GraphQL specification, check out GraphQL’s documentation. Next, we’ll take a look at the structure of a query with GraphQL.
Anatomy of a GraphQL Query
GET /graphql?query={ books(id:12) { authors { firstName, lastName } title, yearPublished, length }
{
Query { // operation type
books (id:12) { // operation endpoint
authors { // requested fields
firstName
lastName
}
title
yearPublished
}
}
}
The above GraphQL query is structured to get author data for a specific book, then return all book data for that specific author. This can all be done with one query that is parsed and handled by the GraphQL server logic. When comparing this to the structure of the same request in REST architecture, the advantages of GraphQL start to become clear. Let’s look at the structure of a REST request below, then focus on some of the differences!
Anatomy of a REST Request
To make the same request to a REST API, the client will need to first make a request to the endpoint with the capability to return data on books, passing in the book id as a parameter:
GET /books/12
This request would likely return an object with all of the data for that specific book, example:
{
"title" : "The Hitchhiker's Guide to the Galaxy",
"authorID": 42,
"yearPublished" : 1978,
"length": 208,
"genre": "Science Fiction"
}
The response in our example has 2 disadvantages over the response for the same GraphQL query:
To get that missing data, we'll need to make one additional request using our authorID:
GET /authors/42
The response to this request should contain all of the data we’re looking for:
{
"firstName" : "Douglas",
"lastName": "Adams"
}
Now that we have all book and author data that we need, the burden of parsing through the response is on the client side. The front-end application must now combine data from the different endpoints in a way that it can use for its desired functionality.
In conclusion, GraphQL offers performance benefits over REST APIs that can pay off for front-end developers. Creating a server using the GraphQL specification can require more setup and writing of predictive server-side logic to parse and handle requests. While the setup costs of GraphQL may be higher than traditional REST architecture, the benefits of more maintainable code, robust dev tools, and streamlined client-side queries usually outweigh the costs.
References & Useful Links: