Meet GraphQL!

Meet GraphQL!

The server-centric approach of REST sometimes makes REST APIs difficult to query elegantly. GraphQL and its Schema Definition Language encourage thinking differently about data exchange by placing the emphasis a lot more on the client’s perspective, thus solving REST’s disadvantages.

We have examined elsewhere that REST’s server-focused approach can make APIs built adhering to it unnecessarily clunky and unelegant to handle for clients. In particular, we’ve established it’s sometimes hard for clients to elegantly access nested resources and to maintain – specifically when attempting the former – good “response efficiency”, i.e. a good ratio between amount of information sent back by the server versus amount actually used.

In the upcoming sections, we’ll take a look at the new kid on the block that has arrived to question REST’s dominance as the de-facto standard in API design: GraphQL.

The New Kid On The Block: GraphQL

Introduction

The new kid on the block isn’t actually that new – GraphQL was developed internally by Facebook in 2012 and made available to the public in 2015. This means GraphQL is already eight years old – eons, then, in the realm of information technology! On the other hand, GraphQL became stable with the introduction of the GraphQL Schema Definition Language to its specification as late as 2018 and still seems to be less widely known as REST, so maybe it still passes as the new kid.

Simply put, GraphQL is a more modern way to query and build APIs that addresses the shortcomings of REST. From the client’s perspective, GraphQL is a query language clients can employ to query data from a server, and from the server’s perspective, GraphQL provides a runtime to respond to such queries.

API Descriptions In GraphQL

The foundation of GraphQL-based data exchange is a description of the API. To standardize such descriptions, GraphQL brings its own notation enabling the description of what types and fields an API accepts and delivers. This notation has been formalized in the form of the aforementioned GraphQL Schema Definition Language, and it is made up of five basic building blocks:

  • Individual fields: Indicate the presence of a certain piece of information having a certain data type (either built-in or user-defined). A field can be marked as mandatory (i.e., non-nullable) by adding an exclamation mark to its type.
  • type: Essentially a named container for a logically related set of fields that represent some object. A type can be used as the data type for the fields of other types, and a type is what a query returns. A type cannot be used as the parameter for a mutation, however – there’s the input type for that.
  • query: Declaration of a function in the API that returns a real-world object (or a list of such objects).
  • input: Special kind of type to be used as the input type for a mutation.
  • mutation: Declaration of a function in the API that performs some state-altering (or state-mutating) operation. If a mutation needs some piece of information, then that piece of information has to be declared by means of an input type, not a regular one.

This all sounds rather abstract, so let’s take a look at a short example.

Suppose you have movies, actors, and characters (the attentive reader might recognize this as a slightly more sophisticated version of the example from the previous blog post) – more about that in the next blog post when we build our demo application, for now, here’s how one could define, say, the actor type in GraphQL schema speak:

type Actor {
    id: ID!
    firstName: String
    lastName: String
    age: Int
    gender: String
    characters: [Character!]
}

As you can see, the notation borrows its basic structure from JSON. Here’s how you would define a query to retrieve such actors:

type Query {
    getAllActors: ActorResponse!
}

(Of course, to make those two examples work, one would have to define more stuff like the Character and the ActorResponse type, and we’ll do just that in scope of the next blog post.)

Those two examples highlight a very important difference between GraphQL and REST: While the latter focuses on resources and which endpoints to expose for clients to query them, GraphQL revolves around the idea of defining the entire API in terms of types and fields.

What’s In It For The Client?

GraphQL provides clients with two major advantages over REST.

Fine-Grained Control Of Delivered Fields

GraphQL’s basic idea of describing an API in terms of types and fields might appear too trivial a concept to be really powerful, but in truth, it is what makes a GraphQL API so amazingly easy to consume for clients: Using types and fields, each client can query the API for precisely what it wishes to consume. When compared to REST, this is a very profound paradigm shift: Rather than the server being in control of how a resource looks like, it’s suddenly the client who’s in charge, being able to control in a very fine-grained way which fields the server should deliver. This means the ratio between the amount of information the server returns versus the amount of information actually used by the client is maximally efficient (assuming that the client queried the server correctly).

Simple Retrieval Of Nested Objects

In my opinion, this is where we enter the realm of pure and absolute awesomeness: Assuming that the server’s implementation of the business domain’s data model permits it, a client’s ability to define which fields to retrieve does not stop on a type’s root level. Rather, if a type is nested within another type, then clients can specify the fields of that nested type, too! And if that type, in turn, contains a nested type, then its fields are accessible as well, and so on. So, theoretically – if the server’s data model allows for it – clients can traverse arbitrary nesting levels in one go just like that. Awesome, innit?

Conclusion: The New Kid Rocks!

GraphQL addresses two of REST’s most significant shortcomings by making API descriptions focus on types and fields rather than resources and endpoints. By doing so, it passes the control of what pieces of information to be delivered to the client, which constitutes a significant paradigm shift in comparison to REST, where it’s almost always the server in charge of what is sent back to the client.

GraphQL has now been around for a while and the ecosystem surrounding it, in my humble estimation, has evolved to a point of maturity where new projects don’t have to be afraid to fly blindly when choosing GraphQL as the foundation to build their APIs on.

As this blog post was quite a lot of text – and quite little of actual code –, we’ll drive home the point in the upcoming blog post by building a demo application exposing a GraphQL API. I bet you’ll like it!