What is GraphQL?
GraphQL is a query language specification written by Facebook and used by them in production since 2012. It aims to achieve a number of things:
- Provide a declarative way to query data from an API in a mobile network friendly way.
- Improve upon the shortcomings of RESTful API architecture.
- Allow for easy interfacing with legacy APIs, and/or many unrelated services.
- Enable developers to iterate quickly on applications without requiring extensive changes to API architecture.
- Facilitate the strict definition of data in an API.
If you’ve come to this article knowing nothing about GraphQL, the most important takeaway is that GraphQL is not a library or framework. It cannot be installed or imported into a project. In order to use GraphQL (which you should definitely consider), you first have to adopt or create your own implementation. With that out of the way, let’s dive right into it.
Brief history of GraphQL
GraphQL was developed as an internal tool at Facebook beginning in 2012 as a tool to deliver News Feed data to mobile devices and borne out of frustration with the disconnect between the process of querying data from traditional REST APIs and the data consumed by mobile application views. In 2015, GraphQL was released as a technical preview to the wider developer community. In November of 2018, the Linux Foundation announced the creation of an open source, neutral foundation for the development of GraphQL.
GraphQL Vs REST
One of the most popular arguments for adopting GraphQL cites many of the drawbacks of a RESTful architecture that GraphQL improves upon. Let’s break some of those down. REST (REpresentational State Transfer) has been the standard in API design for over a decade, and not without reason. REST provides a way for servers to remain stateless, and it normalizes how a client can expect to retrieve data between many unrelated servers. However, REST drawbacks become apparent when a client needs to create relationships between many types, or over large amounts, of data. When a REST request is made, all data under the umbrella of that endpoint is served to the client. A simple example can illustrate the problem with this approach.
In our example, say a we have a job search application where a client application is trying to display a simple bio to the user. This client is only concerned with the displayed user’s name
, a bio
, and the company the user works for. The client sends a request to the /user/id
endpoint, and receives the following response structure:
{ user: { name, dateOfBirth, following, follows, posts, lastActive, bio, likes, companyId } }
Clearly the client has received more information than it explicitly needs about the user. On a mobile network connection with restricted data limitations, this over-fetching issue can quickly become a pain point for the user. At the same time, this request hasn’t fulfilled the client’s need. The /user/id
endpoint responds with a user's companyId
, but the client needs the name of the company the user works for, not its Id
. So, another network request has to be made to another endpoint.
Another issue with REST APIs is that they are inflexible. Modern application development usually involves very quick iteration cycles, meaning that an API that worked last week is not guaranteed to work for updated specifications or developments. If the client is being developed separately from the API, this means that every time the necessary structure of client-side data changes, developers have to rewrite their requests to return the data they want. Since application state is almost never modeled in the same way a REST API is structured, this is usually not trivial.
Advantages of GraphQL
Now that we have an understanding of some of the problems with RESTful API design, let’s take a look at what makes GraphQL so great.
Get only the data you want
GraphQL queries are structured as declarative requests from client to server. If we’re thinking in terms of the same User
data modeling from before, the client can make a HTTP POST request with the following structure:
query { User(id: '123456') { name, bio, company { name } } }
This request is processed by a GraphQL server implementation, which resolves the request using a database or a different API. It then sends the requested data object back to the client:
{ "data": { "user": { "name": "Jimothy", "bio": "A user bio", "company": { "Synergy Solutions" } } } }
That’s it. The client gets exactly the data it requests, and nothing else. The GraphQL server even takes care of resolving nested company
data without making a second request. This concision is an obvious advantage when it comes to loading data over a limited mobile network, and it reduces the developer overhead required to build the correct data model on the client-side.
Faster iteration speed
This declarative data modeling means that as an application changes during development, the type and structure of the data pulled in can be modified with relatively little effort. This is an advantage on projects where there’s not a clear definition of what the final relationships between data will look like, or even what sources it will come from. In addition, setting up a GraphQL server allows developers to abstract away the complexities of a legacy API, or of multiple APIs being pulled into one point of contact. Once that upfront work has been done, the cleaner GraphQL API can be interfaced with from multiple clients easily.
A strong type system that defines structure of data
The GraphQL specification defines a strong type system that needs to be implemented when creating data schemas for the client/server relationship. This creates a type of contract between the GraphQL server and any client that uses it, allowing for error-detection that happens before that code goes into production. In addition, schema typing creates an implicit documentation of your API, allowing for lots of useful interactions like code completion and helpful error hinting.
Wrapping up
GraphQL is a powerful tool for declaratively interfacing with data stores or existing APIs. In a future post, I’d like to explore what use cases are best suited for GraphQL implementations, what the GraphQL ecosystem looks like (in terms of client and server libraries), and which companies have adopted GraphQL.
Thanks for reading.
Originally published at tndl.io on December 2, 2018.