GraphQL Will Do To REST What JSON Did To XML
If you are developing applications, either on the backend or frontend side, you should know what a REST API is and must have heard about GraphQL at any point. The first is a no-brainer for any developer and the latter is spreading quickly among developers that want to be on the forefront of new technologies, after Facebook open-sourced it in 2015.
Haven’t heard of it yet..?
In this article I won’t explain in detail what GraphQL is and how you could best use it (you could find this here or here), instead I will outline its pro’s and con’s against using REST services with a real-life example.
What’s wrong with REST?
Just to be clear: nothing is “wrong” with REST. But as it’s around for a long time already, it has been caught up by newer technologies. If I have to name the biggest problem of REST, it would be its nature of having multiple endpoints instead of just one as we have with GraphQL.
REST APIs are most of the time a collection of endpoints, with each endpoint representing a specific resource. When a client wants to access more than one resource at a time, it requires them to make multiple round-trips to the server to retrieve the data they need.
Also, clients usually have no control over the fields that are returned by an endpoint. The REST API returns all fields that are specified for this endpoint, no matter which content the client has requested — unless you have developed a client request language yourself.
Why should I use GraphQL?
As mentioned before the main advantage of GraphQL over REST services is its ability to send the requested data over just one endpoint. Not only can multiple resources be combined into one output, clients also have control over the fields that are returned.
This is especially useful to Frontend Developers as it takes away a lot complexity in handling data when constructing for example an UI view. This enables them to focus on building applications, rather than spend their time figuring out how to combine endpoints into readable data that can be displayed to the user.
Another advantage of GraphQL is its approach to versioning. With a REST API we would need to add a version parameter to the endpoint in order to make sure the correct data is returned as the API grows. With GraphQL you can just add new fields without having to delete old fields that are no longer used by newer versions of your applications.
Let’s show an Example
Suppose we would have the following endpoints for a REST API, which I (as movie buff) took from The Movie Database API:
- GET
/movie/:movieId
- GET
/movie/:movieId/credits
- GET
/movie/:movieId/reviews
The first endpoint will show us all records for a movie, the second and third endpoint will return specific details for this resource. Have a look at the JSON output from my request to /movie/:movieId
to receive details for the cult movie ‘Fight Club’.
// The return for /movies/:movieId
{
"adult": false,
"backdrop_path": "/fCayJrkfRaCRCTh8GqN30f8oyQF.jpg",
"belongs_to_collection": null,
"budget": 63000000,
"genres": [ ... ],
"homepage": "",
"id": 550,
"imdb_id": "tt0137523",
"original_language": "en",
"original_title": "Fight Club",
"overview": "...",
"popularity": 0.5,
"poster_path": null,
"production_companies": [ ... ],
"production_countries": [ ... ],
"status": "Released",
"tagline": "...",
"title": "Fight Club",
"video": false,
"vote_average": 7.8,
"vote_count": 3439
}
Assuming I only want to show the title
, vote_average
and vote_count
for this movie, we would waste a lot of network and memory resources with the request — both for the client and the server. And this is only for the first endpoint, if we look at the output for /movies/:movieId/credits
and /movies/:movieId/reviews
more fields are returned that we probably wouldn’t use.
// The return for /movies/:movieId/credits
{
"id": 550,
"cast": [
{
"cast_id": 4,
"character": "The Narrator",
"credit_id": "52fe4250c3a36847f80149f3",
"gender": 2,
"id": 819,
"name": "Edward Norton",
"order": 0,
"profile_path": "/eIkFHNlfretLS1spAcIoihKUS62.jpg"
}, { ... }
],
"crew": [ ... ]
}// The return for /movies/:movieId/reviews
{
"id": 550,
"page": 1,
"results": [
{
"author": "Goddard",
"content": "...",
"id": "5b1c13b9c3a36848f2026384",
"url": "..."
}
],
"total_pages": 1,
"total_results": 1
}
So as a Frontend Developer that wants to show details about a movie — including its cast and reviews — I would have to make a request to three endpoints to retrieve this data. Also, I have absolutely no control about which data I receive from these endpoints. So not only would I have to make requests to these three endpoints, I also need to filter out the fields we really need before my application can show this data to the user.
With GraphQL we call this problem over-fetching of information that we don’t need. In general, a GraphQL endpoint would look something like this:
- GET
/graphql?query={ ... }
The query
part will just be a string containing all the fields or the information that we need from the endpoint. As we want to retrieve the title
, vote_average
, vote_count
, cast (name
, character
) and reviews (total_results
) for the movie ‘Fight Club’ this would translate to the following in GraphQL:
// GraphQL query for 'Fight Club', movieId = 550
movie(movieId: 550) {
title,
vote_average,
vote_count,
credits {
cast {
name,
character
}
},
reviews {
total_results
}
}
This query almost exactly represents the output of the endpoint GraphQL returns to us — except the values of course — which contains just the information we want to display in our Frontend application. And although this is just a fictional design, it shows the advantages that GraphQL would have over REST using a real-life example.
Will REST be send to the graveyard by GraphQL?
No. Developers should use the right “tool” for the right “job”, meaning that REST principles will still be used for at least the coming years. Although the sound of having only one endpoint in GraphQL seems like heaven, it can still be over flooded by too complex queries. Also, it is yet another technology developers would have to master. But in the end, XML was (or in some cases still is) used to parse data — although it’s better suited to handle documents — while JSON is far better at handling data.