Graph or not to Graph, that is the Question

Victor Iris
9 min readOct 23, 2020

A GraphQL motivation guide for the first steps on building better APIs

In software development, it is now common to see backend implementations as REST APIs which handle the data requests of a client and up to some extent act as a guard of the database or services where the data resides.

The technology stack for an API varies between companies but the most common ones involve DBMS like MongoDB, MySQL or PostgreSQL with a broad combination of different languages such as JavaScript, Python, and PHP.

A REST API handles HTTP requests from many different endpoints that contain specific logic about how to respond to a certain client with a specific request. The downside is that eventually a REST API may need dozens of endpoints to manage requests for different types of data, thus making it hard to document and maintain.

This and other challenges motivated the creation of GraphQL. A need for standardizing APIs with a flexible, maintainable and fast approach. With a single http endpoint approach of GraphQL, it becomes a technology-agnostic alternative that has a rapidly growing community support.

The history of GraphQL

GraphQL (Graphic Query Language) started in 2012 as a Facebook internal project focused on the improvement of APIs and server-side execution queries. At that time, their mobile client fetched the content from the website into views, requiring a higher network connectivity and causing the app to crash constantly due to the resource overload, thus affecting the user experience. Engineers at Facebook were looking for a way to redesign the data distribution so that the servers would require less resources and the client-side code could be simplified for data handling.
Improving the development on the client side would not only increase the performance of their technologies but make development and maintenance easier, thus increasing their productivity. In 2015 GraphQL became available to the public as an open source specification and now is part of the Linux foundation, being supported by a big community of companies around the world, including GitHub, PayPal, IBM and more.

REST vs. GraphQL

For many years, REST has become the standard for developing APIs due to its features. The “strictness” enforced by REST has allowed developers to have structured access to resources and a more standardized way of sending data across systems and clients. However, the modern challenges on the client-side area start to paint REST APIs as an inflexible standard that can limit the quality of software development. For instance, what happens if the client needs more detailed information or a certain structure of the data that is different from the established one?

Having a REST API would require programming variations on the existing endpoints or perhaps adding new endpoints, which at the same time would require the client-side code to be extended in order to support these new changes in the API. In the same way, updating the client-side features could end up needing a change in the API to satisfy the new data requirements.

The existence of multiple predefined endpoints requires the client-side to perform multiple requests, which consumes extra bandwidth due to the data round-trip time. This also leads to over & under fetching, making the server consume more processing and network resources to fulfill the numerous requests that come from the client side.

Furthermore, with time, software versioning can become a problem. The inevitable constant change of software makes REST APIs degrade as their complexity increases to the point of not being efficient or maintainable. The general reason for the complexity problem with REST APIs is that the server side has to make the ultimate decision of what the client is trying to request and the way this request should be fulfilled.

With GraphQL, the client decides the elements and structure of the response, which also allows it to know ahead of time what the response will be like. So, when the client needs a different response it only needs to change the query that is being sent to the endpoint, liberating the server from the extra code needed to know what to do with a specific request. This optimization eventually leads to a better analysis of the data that is being used by the clients, so that improvements can be made without compromising the existing features .

Philosophy of GraphQL

In software development, there are architectural patterns such as MVC, with the purpose of achieving separation of concerns for improving development and maintenance. In a similar way, with GraphQL, the frontend and backend development can continue without greatly affecting each other’s data handling, because the only thing that is strongly defined in the server is an agreement of the API capabilities.

While working with APIs, documentation becomes crucial. After a new feature is added to the backend of a system, the documentation has to be manually updated and then passed down to the frontend team to know how to connect the view. But due to human errors this process sometimes gets delayed or the documentation itself is inaccurate. As an attempt to solve this, GraphQL has the Schema.

The idea behind it is the representation of an application’s data as a tree of objects, which is defined with the “Schema Definition Language” (SDL) to be the general structure of the API. The GraphQL Schema is just a server-client interaction agreement that is not directly accessible to the user in which the objects are known as part of a types collection with entry points known as root types. They specify an operation to perform on the server and the options include query, mutation and subscription.

Resolver is a collection of functions that generate response for a GraphQL query. In simple terms, a resolver acts as a GraphQL query handler. The resolvers are the part of GraphQL that allow the connection between the data layer and the schema with the use of functions that match with a request. Fortunately, the API takes care of scalar properties (considered basic) and only needs resolvers to be defined by the developer when it is intended to perform an action with a non-scalar type.

By having separate resolvers for each type of the data, the API is able to perform complex queries easily. This means that the user can declare nested queries and the API will still be able to process them. Nevertheless, the database does not store the data in the same way, but just relates the elements with IDs so that the API can build the data object that the client wants. With this concept of resolvers, the client’s role becomes more about deciding how the data is to be structured rather than getting involved with the fetching from the source. Such design makes it possible to reduce the versioning problem and allows abstractions to be made easily, going from an imperative to declarative approach.

For instance, if we needed to make an API for displaying genealogical/family trees we would first need to specify how the data pieces are structured and related. Then, the query resolvers would need to be created for only handling specific operations like for getting the details of a person. Such implementation would vary depending on the technology stack but the concept of simple operations remains constant.

Then from our client, we could request any detail of a “person” as long as there is a valid relation defined. For each request a GraphQL API uses the necessary resolvers and chains back the results depending on the requested data. In this way, clients have more flexible, lighter and yet powerful data access.

Without a declarative fetching, an API needs to perform multiple steps for managing data. First, builds and makes an HTTP request. Upon reception, it structures, cleans up the data that comes back and then stores it for finally being able to use it on a view. In contrast, a declarative approach simplifies the process. The client describes the data requirements on a request that is handled by a standardized library and then it uses the data directly where it is needed, avoiding repetitive data request logic on the code. GraphQL still uses data fetching logic but instead of having it on the code, it takes care of the parsing, storage and networking steps for you. Thus, just leaving to the developer the declaration of the information that expects to receive.

In the real world, a REST API would be like a vending machine, where predefined options are offered to the client. The machine expects to handle requests and responses in the same way. If a product needed to change, a new vending machine would need to be placed on the side to keep allowing clients to be fed with the older one. In contrast, a GraphQL API would be more like a restaurant, where the kitchen has a stock of ingredients that can be combined with each other. The restaurant offers a menu to the client with the entrees and the ingredients that are used on them. When the client asks for an entry of the menu it already knows exactly what is going to be on the plate and may have even asked for certain variations of the ingredients. A menu would act as an agreement or connection between the kitchen and the client, giving flexibility but limiting the client to elements that the restaurant is able to handle individually.

Conclusion

Ultimately, a GraphQL system leaves the complexity to the truly important component, the data. In the past, development of APIs was more focused on covering every single aspect of the requests and steps for building responses, but that leads to logic redundancies and human error. Instead, GraphQL defines a separation of concerns that provides more clarity to the way of dealing with data.

With the schema it brings great granularity to the business data definitions, so that the resolvers can rely upon those definitions for relating resources of a database and allow the API to expose well documented interfaces to the client.

Image source: Medium

The idea of a schema greatly simplifies things by considering a response something that is built upon the continuous relation of different types of data containers, giving more consistent yet flexible logic that improves software development. Then, a client can effectively use the graph query language with flexible grade of complexity for reading, modifying or perhaps watching certain elements of the schema tree.

GraphQL requires a solid server-client agreement that states the most essential data that a user can mold according to its requirements. Although GraphQL is super flexible and optimized it does not totally replace REST APIs, in fact it should not.

The right tool should be used for the right job. This is an approach that works best for projects that are still about to create their business data logic and do not depend on a certain API yet. Otherwise, it could be very costly to migrate all the structure from a REST API service to GraphQL. Nevertheless, with such a growing community and solid principles, this seems promising. We have seen many of our clients at DigitalOnUs start to seriously consider GraphQL for their API creation. It is time for some companies to start getting used to it by wrapping their old services with the power of GraphQL.

References

L. Byron, “GraphQL: A data query language,” 14 September 2015. [Online]. Available: https://engineering.fb.com/core-data/graphql-a-data-query-language/.
E. Olin, “The Linux Foundation Announces Intent to Form New Foundation to Support GraphQL,” 6 November 2018. [Online]. Available: https://www.linuxfoundation.org/press-release/2018/11/intent_to_form_graphql/.
“How To Graphql,” [Online]. Available: https://www.howtographql.com. Apollo,
“Why GraphQL?,” [Online]. Available: https://www.apollographql.com/docs/intro/benefits/.
S. K. Muhammed, “Learning GraphQL By Doing,” 12 March 2019. [Online]. Available: https://blog.digitalocean.com/learning-graphql-by-doing/.
S. Stubailo, “The Anatomy of a GraphQL Query,” March 2017. [Online]. Available: https://blog.apollographql.com/the-anatomy-of-a-graphql-query-6dffa9e9e747.
M. Biehl, GraphQL API Design, API-University Press, 2018.
A. Blanks and E. Porcello, Learning GraphQL, O’Reilly Media, 2018.
“Queries and Mutations,” [Online]. Available: https://graphql.org/learn/queries/.
The GraphQL Foundation, “Schemas and Types,” [Online]. Available: https://graphql.org/learn/schema/.
The GraphQL Foundation, “Introduction to GraphQL,” [Online]. Available: https://graphql.org/learn/.
Medium, “GraphQL: “If there’s no documentation, people aren’t going to be able to use it…” Available: https://medium.com/@scottydocs/graphql-if-theres-no-documentation-people-aren-t-going-to-be-able-to-use-it-5c156641bb20

--

--

Victor Iris

Sr. FullStack Engineer at DigitalOnUs. Passionate about coding new things for a better tomorrow. Experience with PHP, JavaScript, C++ and more.