3 reasons your backend should use GraphQL over REST

Overview
Did REST just get put to rest by GraphQL? In my opinion, kinda! GraphQL brings to the table so many amazing development practices that REST lacks. Although REST is great, and have used it religiously for years, I decided to take a pivot from the certainty of Express backends and try out GraphQL. And the results were…astonishing!
In this article, I’m going to give you 3 reasons why your next project needs to use GraphQL over the REST. And if you’re still using SOAP, we’ll I don’t think you need to read this article, just go here. Let’s jump right in!
Reasons to leave REST
Over my years of being a mobile and backend dev on various projects, I’ve noticed that my so-called “best friend”, REST, and I have some beef. It’s not anything major, but it’s just enough that it makes you want to pull your hair out sometimes…
So, you might be asking, “what’s my beef with REST?”
My top 3 issues with REST are:
- Versioning API’s
- Lack of client-side flexibility
- Over/under – fetching data
I’m going to go into each issue and describe how REST falls short for me and how GraphQL saved the day! Let’s start with versioning APIs.
Versioning API’s
If you’ve ever worked on a large project with a decent user-base, then you probably have dealt with a versioning nightmare before. And if you haven’t I envy you.
For those of you who haven’t dealt with versioning, when you need to make an update to a REST endpoint which requires more params or has a different JSON structure/types being returned, you need to make a new version of the API instead of directly updating the current version.
The reason you version your API is so you don’t break the clients that are using the current version. Also, you can’t assume that clients will update their app to the latest release, so you have to maintain support for older versions. Now, every time you version, you nearly double the maintenance needed for the codebase just by creating a new version of an API that we already had. Good luck telling your devs that…
How does GraphQL solve this?
With GraphQL, you don’t version. Instead, you use a single evolving version where new fields can be added without the client being affected. The reason new fields can be added with no effect is that the client only gets back what it queries for in GraphQL. Since the older client doesn’t know about the new field, it will never be returned, which means no breaks!
Let’s look at the example where we have an API that gets the info about a specific character in a game.
Our team just decided to add a new field to our API that tells you where the character is from. With GraphQL, we can simply add this to our Character
type on the server-side and create a resolver for the hometown
field that we added. Now, future apps can simply add hometown
to their client-side query like such and have the information returned to them.
query GetCharacter { get_character(id: character_id) { name skills hometown // added to new client version } }
But, it’s important to remember that not asking for hometown is also a valid query. So, if your client-side application doesn’t install the new update, no problem! To them, it will look like nothing has changed since they aren’t asking for hometown
in their query. And since GraphQL only returns data that you asked for, they won’t get it!
By having this “ask for what you need” architecture, we indirectly create versions of the API without having to maintain multiple versions like REST 🤮. By doing this, we add flexibility to our client and server-side application, and as we will see, REST is no gymnast!
Lack of flexibility
For me, versioning API’s was enough to sell me on GraphQL, but, if you need some more reasons to switch, let’s take a look at the lack of flexibility that REST delivers to client side teams.
With client-side apps, endpoints are usually created for fetching data for a specific screen or function that the client is looking to deliver to the user. When using REST, you have an endpoint, you call that endpoint and you get back the data structured in the way the REST contract was defined. Once the contract is “signed defining the structure of the data being returned, it’s constant from there on out. You stamped this approval and clients need to conform to that contract and expect all of the data that is being returned to be returned.
So what happens if the frontend devs want another field for their new feature on the screen?
Well, good luck! Even if the field is already available on the backend, the backend team will have to create a new version of the REST API and have that version send back the new piece of data. This ugly dependency cycle continues and continues creating a tight coupling between the work that the frontend team is doing and the backend team is doing. The backend team can’t work ahead of the frontend team and the frontend team is stuck until the backend team is done with the new version of the REST API.
With GraphQL, stuck teams are no more.
No more waiting for the backend team to add some piece of data to the REST API. No more waiting for client teams to tell you what they want in the next version of the API. Both teams can work (for the most part) independently of each other because of the flexibility that GraphQL provides. Backend teams can add new fields that the client teams can access and all the client teams have to do is update their query to add the new field! How f*@king cool!
Now client teams can try new queries and add new features to your app without having to knock on the backend engineers door to give the dreaded, “hey can you add this to the endpoint” talk. Even if they do have to have that talk, because the property isn’t available yet, it’s a simple addition for the backend developer and will likely not be an issue at all.
Now that we’ve looked at versioning and the lack of flexibility that REST-based systems provide. Let’s see how these issues sum to a data fetching nightmare for REST-based projects 😨.
Data fetching nightmare
With REST backends, the whole purpose is to provide a representational state transfer from the backend to the frontend. For instance, retrieving a user’s account information and their current credit status. Although it’s great in theory to provide API’s exclusively to get specific chunks of information, it forces frontend developers into stringing together API calls that result in under-fetching or over-fetching data from the backend. Let’s look into what these two issues really mean and how GraphQL resolves them for you!
Under-Fetching Data
This happens due to the nature of REST services. You create an endpoing which constructs JSON data that represents the state of the backend and return that data to the client. The issue with this happens when that state does not provide enough data back to the client for the needed functionality. Consequently, the client then has to make another network call, sometimes with data from the previous call, to get enough information to present the UI to the user.
As you can see, we’re stacking network calls on the client due to the limitations of our REST service. When you add more networking calls, you create more latency before the UI can be presented to the user. This is the classic n+1 call issue with REST services where you have to always make one more call to get all of the data you need. Wouldn’t it be nice if we just got all of the data we needed with one call?
GraphQL solves this issue by giving the client the ability to query for EXACTLY what they need. As a result, each view on the client-side can make one network call to the GraphQL server and nothing more. This takes a lot of stress off the frontend developers and allows them to not have to worry about stringing together id’s to make consecutive REST calls to get all of the data they need! It also brings down latency time as there is only ONE call to the backend server.
Over-fetching data
Over-fetching data is when the backend service gives back more data than you need. For example, you want to get the usernames of users based on their user-id, but the backend service gives you the complete user object back instead of just the username string; you’re over-fetching data. The more data that is being downloaded, the more latency, and potentially more cost for the user to use your application.
Again, GraphQL takes care of over-fetching data by only returning the data that you’re requesting. So, instead of returning the whole user object, we can specify to only return the username from the user object inside of our query.
query GetUsernames { getUsers(ids: user_id) { // returns user object username } }
As you can see in the example above, instead of returning the whole user object, we only get the username returned from the backend because that’s what we asked for. No more, no less!
Wrap Up
In this article we looked at the three main issues that I have with REST backends: versioning, lack of flexibility, and over/under-fetching of data. We also looked at how GraphQL solves these issues by creating a single endpoint that is ever-expanding to meet the needs of your client-apps as well as providing abilities for client-apps to get exactly the data they want how they want it.
Also, if you’re a backend engineer and want to move your REST service to a GraphQL API, just know, you can do it! In fact, hundreds of companies like Facebook, Shopify, and more have already done it! Remember GraphQL doesn’t care about where the data is coming from, it’s simply a query language between two parties. You can easily wrap a REST API in a GraphQL endpoint as long as the data in the “contract” is being returned! If you want to learn more about GraphQL, click here to go to their docs.
Let me know what you think about GraphQL in the comments down ⬇️ below! Will you be using it in your next project?
If you liked today’s content, make sure you subscribe to the newsletter down below! As always, thanks for taking the time to unwrap some bytes with me. Cheers! 🍻