Developed by Facebook in 2012 and publicly released in 2015, GraphQL is at this point a well established alternative to Rest and other web API architectures. Lineate has chosen GraphQL as its preferred approach to greenfield API development and as its preferred approach to extension of existing APIs where mixed paradigms are appropriate or iterative migration to a new paradigm is desirable. So, why use GraphQL in the first place, and what should your development teams watch for and be aware of when you choose this technology?
Out of the box, GraphQL isn’t inherently faster or slower than other Web API architectures. Your development teams have some work to do before they get to fast. However, GraphQL’s core feature of exposing your full business domain model as a single queryable relation of entities all the way to the front end allows for performance benefits that are not available when working with other architectures.
Front end developers, or other clients of a GraphQL API have the luxury of being able to ask for exactly the data that they need, and only the data that they need in order to satisfy a given use case as its requirements evolve. Moreover, when working with a mature GraphQL schema, they can more often than not do this without requiring any changes to be made to back end services. Similarly, once the business domain entities and the relationships between them that need to be exposed via the API have been established, API developers can focus on overall API performance rather than being required to define an ever expanding set of service endpoints in order to satisfy new feature requirements. Over the course of development this results in a highly performant API, client applications that make very efficient use of data transfer resources, and users that are delighted with the perceived “snappiness” of the application.
As noted above, GraphQL allows API developers to expose a representation of the business domain as a single queryable service comprised of domain entities and the relationships between them. In many ways, this is similar to how a relational database exposes a queriably interface of interconnected domain entities. However, GraphQL encourages schema modeling at a higher level of abstraction as compared to a well designed and normalized relational database schema. As such, a well designed GraphQL schema will tend to directly correspond to the business domain schema as business users and engineers might quickly draw it on a white board. The result is an API design that facilitates discussion and discovery between technical and non-technical stakeholders and which allows query use cases to be implemented largely as they are described.
GraphQL is super cool, but it is not magic. If your API developers aren’t paying attention, default approaches to implementing GraphQLs data resolver pattern can result in slow and very chatty interactions with the database. Essentially the well known N+1 query problem that is familiar to users of any ORM. These problems are often most easily addressed using a query batching and result caching as part of the API implementation. This approach can give significant speedup without requiring a departure from the default resolver paradigm. Check out Facebook’s data loader project for a tool that simplifies querying across disparate data sources in the backend and which easily enables batching and caching. When performance is critical, API engineers can also consider short circuiting the resolver pattern in order to translate the GraphQL query abstract syntax tree directly into native SQL, potentially reducing N+1 queries down to a single query against your back end database. Judicious use of this admittedly more complex approach can result in blazing fast API response times. Performance considerations are not just for the backend API developers. Front end developers making use of GraphQL have a great deal of power and freedom in how they will query the back end. GraphQL is awesome in that it allows developers to request just the data that they need in a single query. However, as with relational databases, large complex queries run the risk of bogging down the server and front end developers need to be aware of this. Sometimes decomposing a single large query into several smaller queries is the correct way to achieve the performance that is required. Grab it all in one go is ideal when it works, but not always the best most efficient way.
GraphQL is a compelling, modern alternative to Rest and other web API architectures. Its core strengths are efficient data transfer, and significant flexibility and power for developers. Developers also tend to agree that it is a heck of a lot of fun to use, and as we all know, happy developers are productive developers! GraphQL allows you to map your “white board” domain models more or less directly to your API schema. You can quite literally query what you draw during your domain design sessions. GraphQL excels at modeling complex business domains and is an ideal solution for APIs that expect to serve multiple different consumer applications. Finally, when implemented thoughtfully, GraphQL APIs can be very performant, but developers absolutely do need to pay attention to data access patterns in order to realize that performance.