An Alternative to REST API
In the early 2010s, the Facebook development team was tasked with streamlining the mobile app and kept bumping up against the limitations of REST APIs. Loading a user’s posts, with all of the posts’ likes, was proving a challenge. The posts were stored in a MySQL database, while the likes were housed in a Redis store. This separation bogged down the network with extra, unnecessary data and resulted in two different endpoints, one with likes and one without. The solution Facebook arrived at was to overhaul the REST system entirely and replace the multiple “dumb” endpoints with a single “smart” endpoint that could handle a multitude of complex queries.¹
“GraphQL is a query language for your API that shifts the contract between clients and servers that allows the server to say ‘these are the capabilities that I exposed’ and allows the clients to describe their requirements in a way that ultimately empowers product developers to build the products they want to create.” — Dan Schafer, GraphQL Co-Creator
GraphQL is a syntax for web APIs that lets a client specify the exact data it wants back from the server. Utilizing a type system to describe data, programmers are able to build requests that fetch information from multiple data sources in a single API call. The backbone of GraphQL is threefold:
The schema is the true star of GraphQL and acts as the central hub of all data for an application. The schema uses a strong type system to define all the capabilities of an API and offers a unified endpoint for all client data requests. Comprised of object types that specify exactly what fields are available to query, the GraphQL looks similar to a database schema, but the two are completely independent of one another. This decoupling frees the API queries from being limited to returning only database documents and once the schema is established, allows front-end and back-end teams to work entirely independent of one another.
If you think about GraphQL as a personal assistant, tasked with running all your errands for you, the resolvers are the list of varied errand locations. If you ask your personal assistant to pick up your dry-cleaning, you are going to have to specify at what cleaners the garments are. Similarly, the resolvers tell the GraphQL server where to look to find the data requested for an incoming query.
Every field in the schema is tied to a resolver — a function — that is able to return objects or scalars. As the Apollo documentation states, “whenever a client queries for a particular field, the resolver for that field fetches the requested data from the appropriate data source.”² The results will be either:
- Data of the type required by the resolver’s corresponding schema field (string, integer, object, etc.)²
- A promise that fulfills with data of the required type²
Queries are the request sent by the client to the GraphQL server for data. The structure of the query dictates the exact shape of the data that will be returned.
The above query sent from the client takes the parameter of “book id” and requests from the GraphQL server the title and genre of that id. The returned data contains the requested data, and only the requested data, no more or less.
Pros & Cons
- The schema provides a single “source of truth” for your application.
- Calls are handled in a single round-trip — clients get only what they ask for.
- Data types are strongly defined which reduces chances for miscommunication between client and server.
- Open sourced libraries for GraphQL extensions available.
- Can build on top of existing REST APIs
- REST APIs have been the standard for long enough that there is a learning curve for developers used to REST.
- Puts the burden of much of the work for a data query on the server which adds more complexity for server-side programmers.
- Does not have many of the security features of REST and require manual definition of rate limits.
- The GraphQL schema has to be maintained.