GraphQL – The nemesis of REST?

by Sherwin Jaleel
2K views

If you’re like me, GraphQL was perhaps a blip on your technology radar, but now you’re scrambling to intercept its ubiquity. GraphQL has been picking up steam since 2016, and its adoption has steadily grown. GraphQL has risen to be lauded (by some) as the natural successor to REST. There has been a fervent community adoption embracing the technology and within a year of GraphQL being open sourced Github adopted it to implement their public API. Github adoption is significant because it was Github that helped popularised REST technology.

What is GraphQL?

One way to explain what GraphQL is to describe the problem it solves.

Since its development in 1970 by IBM, the Structured Query Language (SQL) has been used to access and manipulate data stored in databases. SQL, though simple, is powerful. It enables users to communicate with a database to retrieve and manipulate data that they are interested in.

For example, if a developer wants the Name, Age and the Tweet titles for a Person with the first name of “Mary”, from a SQL database with tables Person and Tweets, they will write the SQL on the left.

If the developer was to do that with REST, how would they do it? Perhaps define an endpoint to return the Name, Age and ID of a Person with the first name John and then query another endpoint with the same ID for the TweetType for all their tweets. But what if the application, later on, wanted a list of just the Age and Tweet type for a Person whose first name is “John”?  The SQL for this request would be something like the one on the left.

If this were REST, the developer would probably define another set of endpoints. However, the approach of an endpoint per query is not scalable. An alternative approach could be to define an endpoint that returns all data for all the Persons and their tweets and then apply filters at the client-side. The second approach is generic but bandwidth expensive (what if there were thousands of Persons and Tweets in the database?). Not only that clients will have to process the returned data to extract the subset of data that they are interested in.

SQL is excellent at slicing and dicing data. What if we can bring the power of SQL to the API world? That’s what GraphQL aims to do. GraphQL is a Query Language – that’s what the QL stands for. With GraphQL you query APIs quite similar in principle to SQL querying databases. The querying approach is much more efficient than traditional methods (such as REST). GraphQL can work with any database – relational, key/value pairs, document stores. It can also be used in front of a traditional REST API (my favourite architectural pattern for GraphQL). Unlike REST (which is tied to the HTTP protocol) GraphQL can operate over multiple transport protocols. GraphQL doesn’t deal with authentication, authorization, compression, caching – all that jazz is your responsibility. Before we evaluate GraphQL in comparison to REST, it’s imperative that we first understand its anatomy.

The Anatomy of GraphQL

GraphQL Specification

GraphQL is not a library but a specification. The specification describes the language and grammar to draft queries, define schemas and validate syntax. Rules are defined for the GraphQL Query Language as well as the Schema Definition Language (SDL). GraphQL doesn’t prescribe the software language to use to implement the specification.

The full GraphQL specification: https://spec.graphql.org/June2018/

GraphQL Server

A GraphQL server is a server-side implementation of the GraphQL specification. A server delivers the data that the Clients asked for. In other words, a GraphQL server exposes data that GraphQL client applications can query. The GraphQL Server checks if the GraphQL Client Query is valid against a GraphQL Schema, once validated it executes the corresponding GraphQL Schema Resolver function (for read request) or Mutation function (for write requests) to carry out the requested operation. The GraphQL Server subsequently prepares the data and returns it to the client. Several vendors in the market have implemented GraphQL clients and servers using the GraphQL specification. Examples include Apollo, Relay (GraphQL Client for React) etc.

GraphQL Schema

A GraphQL schema is at the core of any GraphQL server implementation. It describes the functionality available to the GraphQL Client. GraphQL schema defines the structure of valid queries and the return data types. It is the language the GraphQL Client & Server use to communicate under. GraphQL has its own language to defines a GraphQL Schema: The GraphQL Schema Definition Language (SDL). The syntax for SDL is also part of the GraphQL specification.

The SDL is very intuitive yet simple, and extremely powerful. The main operation constructs of a GraphQL schema are:

  1. Query
  2. Mutation
  3. Subscription

Query

The image above shows a part of a GraphQL Schema. The Schema has three queries, i.e. allPersons, getPerson and getTweets defined using the SDL. GraphQL has a list of built-in Scalar Types, i.e. ID, int, float, string, Boolean. Types are not only limited to these scalar types but can also be another Object Type or Enumerations. The image also shows the other SDL constructs, such as Field, Type, Object Type and Enum Type.

Some queries allow us to pass in arguments, such as the getTweets query which takes the first name (fn) of the Person who’s Tweets we are interested in. 

Mutation

Mutation operation is used to amend data. e.g. To create a new Tweet for a person. Similar to Queries, Mutations can also take arguments and returns values. 

Subscription

The GraphQL Subscription operation enables the server to push updates to the client.

GraphQL Client

GraphQL Client is the client-side implementation of the GraphQL specification. A client is software code (can be written in several languages) that makes a query (more on this later) request to a GraphQL Server. GraphQL clients are part of the systems of engagement applications (such as a mobile app, a React Web client etc.)

GraphQL Client Query

A GraphQL client initiates either be a read or a write request. A GraphQL Query defines and encapsulates this request. A GraphQL Query is a simple string (it follows the GraphQL Specification) that is parsed by the GraphQL Server which responds with data (usually as a JSON). 

 The query on the left  is an example of a query to get the Name, Age and Tweet titles for a Person with the first name of “Mary”:

The query on the left is another example to get the Age and Tweet type for a Person whose first name is “John.

Queries are analogous to REST’s GET, and they allow to ask the server for data. However, in comparison to REST, GraphQL provides flexibility to ask for exactly the data needed and, in the shape, (structure) it is needed. As can be seen in both the examples above once the schema is defined, clients can vary the queries they execute against the schema. This is the flexibility GraphQL brings.

REST – Its Limitations

Developers have embraced the mainstay of the hugely successfully Representative State Transfer (REST) architecture for a considerable time. With REST everything is a “resource”. However, the “resource” based architecture of REST becomes problematic when the relationships between the “resources” get complex and consequently, the underlying API generates a lot more round trips. Another challenge with REST is that applications that do not need all the data of URI based REST endpoint are obliged to receive the data anyway (over fetching). The other end of this scenario is when developers build more fine-grain API that resulted in far more round trips for an application to get the data it needed (under fetching). These issues were demonstrated in the examples above. REST has been a foundational architecture of APIs for well over a decade; nevertheless, it has several significant limitations, especially in a world of data-intensive social applications. 

GraphQL – Its advantages over REST 

GraphQL brings simplicity and elegance to data retrieval in the API world. Data is presented via a common endpoint on the GraphQL Server, thereby eliminating ad-hoc endpoints and roundtrip. GraphQL queries are simple and elegant (quite like SQL). Because data is defined on the server with a graph-based scheme (the SDL we saw in the section above), data can be delivered as a package rather than through several backend calls. In the example above there was a single endpoint to retrieve data for Persons and Tweets. In traditional REST, this would take several endpoints. GraphQL enables retrieval constraints (fn = John and FN = “Mary” in the example above) that are declared with a declarative-hierarchical query and these are applied to a single endpoint.

GraphQL – Three Key differentiators

  1. REST can generate many roundtrips. GraphQL in comparison has far fewer round trips
  2. The data type systems in REST are very narrow and limiting. GraphQL has a comprehensive type system,
  3. REST has poor discoverability unless augmented solutions such as HATEOAS or Swagger. GraphQL is self-describing and natively discoverable.

Conclusion

I do not think we can banish REST from our technical lexicon. However, it has to be acknowledged that there are significant issues with REST, especially in the domain of data-intensive social applications. GraphQL may not bring about the complete demise of REST. However, it brings a paradigm shift into the status quo for how APIs are built and consumed.

Is GraphQL the nemesis of REST? I don’t think so. Nevertheless, being “less chatty” with fewer backend calls, being able to “cherry-pick” data fields, being able to define “on the fly” the shape of the returned data and doing all this against a single endpoint is a game-changer!

You may also like

Leave a Comment