After only two and a half years of existence, GraphQL has made its way to the forefront of API development. In this article, we explain why developers love GraphQL and unveil the major reasons for its rapid adoption.
One of the biggest problems with most APIs is that they’re lacking strong contracts for what their operations look like. Many developers have found themselves in situations where they needed to work with deprecated API documentation, lacking proper ways of knowing what operations are supported by an API and how to use them.
A GraphQL schema is the backbone of every GraphQL API. It clearly defines the operations (queries, mutations and subscriptions) supported by the API, including input arguments and possible responses. The schema is an unfailing contract that specifies the capabilities of an API.
The GraphQL schema is an unfailing contract that specifies the capabilities of an API.
GraphQL schemas are strongly-typed and can be written in the simple and expressive GraphQL Schema Definition Language (SDL). Thanks to the strong type-system, developers are getting many benefits that are unconceivable with schemaless APIs. As an example, build tooling can be leveraged to validate API requests and check for any errors that might occur in the communication with the API at compile-time. You might even get auto-completion for API operations in your editor!
Another benefit of the schema is that developers don’t have to manually write API documentation any more — instead it can be auto-generated based on the schema that defines the API. That’s a game-changer for API development!
Developers often describe the major benefit of GraphQL with the fact that clients can retrieve exactly the data they need from the API. They don’t have to rely on REST endpoints that return predefined and fixed data structures. Instead, the client can dictate the shape of the response objects returned by the API.
This solves two problems commonly encounter with REST APIs: overfetching and underfetching.
With GraphQL, the client can dictate the shape of the response objects returned by the API.
Overfetching means the client is retrieving data that is actually not needed at the moment when it’s being fetched. It thus drains performance (more data needs longer to be downloaded and parsed) of the app and also exhausts the user’s data plan.
A simple example for overfetching would be the following scenario: An app renders a profile screen for a user which displays the user’s name and birthday. The corresponding API endpoint that provides the information about specific users (.e.g
/users/<id>) is designed in a way that it also returns the address and billing information about each user. Both are useless for the profile screen and therefore fetching them is unnecessary.
Underfetching is the opposite of overfetching and means that not enough data is included in an API response. This means the client needs to make additional API requests to satisfy its current data requirements.
In the worst-case, underfetching results in the infamous N+1-requests problem. This describes a situation in which a client requires information about a list with
n items. However, there is no endpoint that would satisfy the data requirements by itself. Instead, the client needs to make one request per element to gather the required information.
As an example, consider a blogging application where users can publish articles. The app now displays a list of users, where each user element should also show the title of the last article published by the respective user. However, that piece of information is not included when hitting the /usersendpoint to get the list data. The app now needs to make one additional request per user to the
/users/<id>/articles endpoint, only to fetch the title of the latest article.
Note: With REST APIs, the issues of underfetching is often tackled by tailoring the payloads of the API endpoints to the client’s needs. In the example, this would mean that the title of the last article of each users is now also returned by the /users endpoint. This approach might seem like a good solution at first, but it hinders fast product development and iterations cycles because any redesigns of the app will often require changes of the backend which are a lot more time-consuming. Learn more in the next section.
GraphQL makes frontend developers’ lives easy. Thanks to GraphQL client libraries (like Apollo, Relay or Urql) frontend developers are getting features like caching, realtime or optimistic UI updates basically for free — areas that could have entire teams dedicated to work on them if it wasn’t for GraphQL.
Increased productivity among frontend developers leads to a speedup in product development. With GraphQL, it is possible to completely redesign the UI of an app without needing to touch the backend.
“We are product people — and we designed the API that we wanted to use to build products.” Lessons from 4 Years of GraphQL, Lee Byron
The process of building a GraphQL API is vastly centered around the GraphQL schema. Hence, you’ll often hear the term schema-driven development in the context of GraphQL. It simply refers to a process where a feature is first defined in the schema, then implemented with resolver functions.
Following this process and thanks to tools like GraphQL Faker, the frontend developers can be productive already once the schema was defined. GraphQL Faker mocks the entire GraphQL API (based on its schema definition), so frontend and backend teams can work completely independently.
To learn more about the difference between schema definition and schema implementation, be sure to check out this article.
The idea of schema stitching is one of the newer ones in the GraphQL space. In short, schema stitching allows to combine and connect multiple GraphQL APIs and and merge them into a single one. Similar to how a React components can be composed out of existing ones, a GraphQL API can also be composed out of existing GraphQL APIs!
Similar to how a React components can be composed out of existing ones, a GraphQL API can also be composed out of existing GraphQL APIs!
This is extremely beneficial for client applications that would otherwise need to talk to multiple GraphQL endpoints (which can often happen with a microservice architecture or when integrating with 3rd-party APIs like GitHub, Yelp or Shopify). Thanks to schema stitching, clients only deal with a single API endpoint and all complexity of orchestrating the communication with the various services is hidden from the client.
GraphQL bindings take the idea of schema stitching to the next level by enabling a simple approach to reusing and sharing GraphQL APIs.
It is only a two and a half years since GraphQL was officially released by Facebook and it is incredible how much the entire GraphQL ecosystem has matured since then.
When it came out, the only tooling available for developers to use GraphQL was the graphql-js reference implementation, a piece of middleware for Express.js and the GraphQL client Relay (Classic).
Today, reference implementations of the GraphQL specification are available in various languages and there’s a plethora of GraphQL clients. In addition, lots of tooling (like Prisma, GraphQL Faker, GraphQL Playground, graphql-config,…) provide seamless workflows and make for an amazing developer experience when building GraphQL APIs.
The GraphQL community is also growing rapidly. Many small and big companies have started using it in production and more and more GraphQL Meetups are being founded all over the world. There even are entire conferences that are exclusively dedicated to GraphQL:
- GraphQL Europe (Berlin)
- GraphQL Day (changing locations, first edition in Amsterdam)
- GraphQL Summit (San Francisco)
In this article, you have learned why GraphQL is the API technology of the future. The advantages it brings to the table and the various ways how it benefits developers and improves workflows are a game-changer for how APIs are built and consumed.
If you want to get started with GraphQL, here a few resources to help you get your feet off the ground quickly: