GraphQL vs REST
GraphQL vs REST – take either side of the argument that you want. The reality is that both technologies have their helpful uses. The talk of GraphQL into the conversation around API technologies is relatively recent, but its adoption rate has been promising for GraphQL’s staying power. REST framework was introduced in the early 2000s and today it is the most popular API framework.
Is it one or the other?
Depending on the use case, GraphQL can be a great supplement or alternative to REST. Many pundits frame the conversation as one or the other. At Aloi, however, we believe that the two can exist in harmony to achieve your goals with APIs.
REST is widely adopted which make things easier in technology. Additionally, the framework clearly defines that entities and CRUD actions are assumed. Like any framework or technology, REST has its limitations. Where REST falls short, GraphQL often excels. GraphQL does a great job of executing complex actions and intuitively associating relationships within the data model. Additionally, GraphQL allows you to fetch only the data you are requesting from an API.
As the incumbent, it makes most sense to look at the most common shortcomings of REST and how you might be able to leverage GraphQL in these ways.
REST at a Glance
Representational State Transfer (REST) is an architectural style that outlines standards for creating web services. It defines a set of constraints that allows computer systems to communicate with each other.
In RESTful systems, the client-side and server-side are independent of each other. The two systems can communicate without the knowledge of each other’s implementation. Also, changes on one server can be made without affecting the operations on the other server. It allows each server to evolve independently. As long as the client-side knows the format of the server-side’s messages and vice versa, they can keep communicating with each other.
Systems built following the REST architecture are stateless. This means it is not necessary for the client to know the state of the server and vice versa. The servers are able to understand each message that they received without prior knowledge of the previous messages.
The server provides paths, also known as endpoints, to its resources using URLs. Then, the client makes requests using HTTP verbs such as GET, POST, PUT, and DELETE through the URLs. The server responds to the client’s requests by sending the requested resources, confirmation of successful action, or error codes when the request is not fulfilled.
Shortcomings of REST
The past decade saw the rise of REST paradigm and it has become the unofficial standard for designing web APIs. Its architecture is behind most web-based applications that we use today.
However, rapidly changing requirements of the client have highlighted the inflexibility of REST APIs. Large data, real-time information, and efficient communication are just some of the rising demands of modern applications.
To illustrate the issues with REST, imagine a simple social media platform where users can create posts and follow each other (think: Twitter). Its REST API has the following endpoints:
where /users will return data about all the users in the platform, /[user-id] will return information about a specific user, /[user-id]/posts will return a user’s posts, and /[user-id]/following will return a list of users that a specific user follows.
Consider the scenarios below that show various issues with REST.
REST APIs are typically designed with fixed data structures. That is, requests to each endpoint will return the same structure of data regardless of the client’s needs. Overfetching happens when the client downloads more information that it needs.
In our social media API above, the /users endpoint will return the following data structure:
A client that wants to display a list of usernames will send a request to this endpoint and will receive an array of user data as described above. However, the server response contains information that is useless to the client such as first-name, last-name, birthday, and so on.
Underfetching happens when an endpoint does not provide all the information required by the client. Consequently, the client will have to make additional requests to download everything it needs. This scenario usually leads to increasing requests.
For example, a client application wants to display a list of first and last names of users that a specific user follows. First, the client will send a request to /following which will return an array of user IDs. Then, to retrieve the first and last names, the client will have to make additional requests to /[user-id] for each user on the list.
A single request can escalate to more requests especially in cases of underfetching. Complex applications dealing with large sets of data will eventually suffer significant performance loss due to repeated request for resources. While workarounds can be developed that the clients code, it does not offer an efficient solution.
GraphQL vs. REST
GraphQL was developed to resolve the shortcomings of REST and cope with the dynamic changes in clients’ needs by representing all of the data related to an application in a single graph. Its flexibility and efficiency directly address the client requirements while maintaining the advantages that the REST architecture provides.
Addressing Overfetching and Underfetching
Consider the scenarios described in the previous section which resulted in fetching useless information or making more requests to the server. Because GraphQL provides a flexible query language, the client can request specific data requirements and will receive the exact structure. In short, GraphQL allows you to retrieve exactly the data you want in a single query – nothing more or less.
A client may request for usernames using the following query:
The server will return with a list of usernames without unnecessary data. On the other hand, if the client wants to display the first and last names of a user’s following list, the query may look something like:
The server will return the exact data required by the client without sending additional requests.
Efficient and Rapid Iterations on Client-side
Another issue addressed by GraphQL is the changes in the client-side and its effects on resource consumption. In REST, the data structure is unchanged regardless of the client’s requirements.
When the client application evolves, it typically needs more (or less) resources from the server. In each iteration, the client will have to address underfetching and overfetching under the REST paradigm. Hence, development productivity on the client-side is affected. This does not allow rapid iterations in the client application which is common with products that incorporate user feedback.
In GraphQL, the client can request data according to its needs and will receive resources following its specifications. Any changes on the client-side can be made without any extra work on either client or server.
Addressing Reliance on HTTP
REST architecture takes advantage of the core HTTP methods. It allows understandable and predictable API behavior. However, it sacrifices flexibility which results in inefficient implementation.
In contrast, GraphQL provides three schema types: Query, Mutation, and Subscription. Queries handle fetching of data while changes are usually managed by mutations. However, the implementation of the GraphQL API and its operations are totally up to its author. There are no specifications on how resources are modeled which allow far greater flexibility. The focus is on how the data is queried and not how it is modeled.
Overview of Differences
Below is a brief breakdown of some of the key differences between REST and GraphQL.
So what should you use?
At the end of the day, an API is published code for someone else to consume. That might be you in a few months, or your friend, or another company.
REST is much more manageable to consumer in cases in which the consumer is closer to you. There are likely no major shortfalls in the capabilities of REST if you are strictly dealing with internal consumers (i.e. future, your team, etc.). However, as your consumer becomes parties beyond arms’ length, you have far less of an understanding of how exactly those consumers will be using your published services. In these cases, GraphQL can ease the burden for consumers and ultimately relieve you of support tickets while eliminating the friction of using your services.
For your internal consumers, use REST to :
- Create microservices for resources (entities)
- Perform basic CRUD operations
- Create internal standards for REST/HTTP
For external consumers, use GraphQL to:
- Compose GraphQL schemas for widely used external services
- Define resource relationships in GraphQL
- Perform Elaborate actions beyond CRUD7
Aloi uses GraphQL with REST
Aloi makes connections between software applications easier. That means that we need to adapt to the API community in the ways it currently exists with an attention for the ways in which it is evolving. Most APIs are RESTful. Accordingly, we interact with REST APIs while leveraging GraphQL as a transform layer on our platform. In this way, our users can continue to work in the framework they are comfortable with while utilizing GraphQL for its interface (GraphiQL) and intuitive query language.