As we all know, REST
is the most common way most developers use to send data over HTTP
. And the advent of GraphQL
is seen as a revolutionary alternative to legacy REST APIs
.
REST
What?
REST is an API design architecture used to implement web services. RESTful web services allow systems to access and manipulate textual representations of web resources using a set of predefined stateless methods such as GET, POST, PUT và DELETE
.
Furthermore, server and client implementation is usually done independently, client-side code can change without affecting how the server works, and vice versa. In this way they are modularized and discrete.
The core idea of REST is that everything is URL defined. In its simplest form, we will access the resource with a GET request to the resource’s URL and return a JSON response (or something similar depending on the API).
For example, GET / movies / 1
1 2 3 4 5 6 7 8 9 10 11 | <span class="token punctuation">{</span> <span class="token property">"title"</span> <span class="token operator">:</span> <span class="token string">"Joker"</span> <span class="token punctuation">,</span> <span class="token property">"releaseDate"</span> <span class="token operator">:</span> <span class="token string">"August 31, 2019"</span> <span class="token punctuation">,</span> <span class="token property">"director"</span> <span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"firstName"</span> <span class="token operator">:</span> <span class="token string">"Todd"</span> <span class="token punctuation">,</span> <span class="token property">"lastName"</span> <span class="token operator">:</span> <span class="token string">"Phillips"</span> <span class="token punctuation">,</span> <span class="token property">"education"</span> <span class="token operator">:</span> <span class="token string">"Tisch School Of The Arts"</span> <span class="token punctuation">,</span> <span class="token property">"nominations"</span> <span class="token operator">:</span> <span class="token string">"Academy Award"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
This is a movie endpoint .
Advantages
One of the main advantages of REST is that REST is extensible. The separate client and server architecture allows developers to scale products and applications indefinitely without much difficulty.
In addition, REST APIs have a high degree of flexibility. In fact, since the data is not tied to a resource or method, REST can handle different call types and return different data formats. This allows to build APIs that meet the specific needs of the user.
Defect
Most web and mobile applications developed today require large data sets combining related resources. Accessing all that data to get everything you need using the REST API requires many “round trips”.
For example, if you want to retrieve data from two different endpoints, you have to send two separate requests to the REST API.
Another common problem encountered with REST over-fetching
and under-fetching
. This is because the client can only retrieve data by hit
the endpoints and returning the fixed data structure of that endpoint. As a result, they cannot get exactly what they need and suffer from redundant or data-deficient fetch.
- Over-fetching is when the client retrieves more information than the application actually needs.
- Under-fetching is when the endpoint doesn’t provide all the requested information, so the client has to make multiple requests to get everything the application needs.
GraphQL
What?
GraphQL is an API design architecture that takes a different, more flexible approach. The main difference between GraphQL and REST is that GraphQL doesn’t deal with resources dedicated. Instead, everything is treated as a graph implying that it is interconnected.
This means we can use the GraphQL query language to tailor the request match exactly to what we need. In addition, it allows to combine different entities into a single query.
For example, a GraphQL query retrieves the movies list:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <span class="token punctuation">{</span> movies (id <span class="token operator">:</span> <span class="token number">1</span> ) <span class="token punctuation">{</span> title releaseDate director <span class="token punctuation">{</span> firstName lastName education nominations <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Advantages
Every time you modify your application’s UI, it is very likely that your data requirements will also change, meaning you will need to fetch more or less data than before. GraphQL makes this iteration quick because it allows developers to make changes on the client side without messing up the server.
Additionally, with GraphQL, developers can have a better understanding of the data required at the back-end and how the available data is being used because each client will precisely specify the required information. This way, we can stop using fields that the client no longer uses to improve API performance.
GraphQL defines API capabilities using the strong type system, so that the client knows how it can access the data. The schema allows both the front-end and the back-end to know the structure of the data and, therefore, can work independently of each other.
Defect
GraphQL uses a single endpoint instead of following the HTTP specification for caching. Network layer caching is important because it can reduce traffic to the server or keep the data accessed regularly with the client via the CDN.
Also, GraphQL isn’t the best solution for simple applications because it adds complexity – with types, queries, resolvers.
GraphQL vs REST
Let’s go through an example comparing GraphQL and REST to see the similarities and differences of both of these API design architectures.
Let’s say you have an online store and you want to feature your latest products in the product catalog. The first step should be to fetch data about products:
GET / api / products
1 2 3 4 5 6 7 8 9 10 11 12 13 | <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token property">"title"</span> <span class="token operator">:</span> <span class="token string">"Table lamp"</span> <span class="token punctuation">,</span> <span class="token property">"desc"</span> <span class="token operator">:</span> <span class="token string">"Features a ceramic base and antique brass accents."</span> <span class="token punctuation">,</span> <span class="token property">"price"</span> <span class="token operator">:</span> <span class="token string">"$178"</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token property">"title"</span> <span class="token operator">:</span> <span class="token string">"Floor lamp"</span> <span class="token punctuation">,</span> <span class="token property">"desc"</span> <span class="token operator">:</span> <span class="token string">"Geometric floor lamp with ivory linen shade."</span> <span class="token punctuation">,</span> <span class="token property">"price"</span> <span class="token operator">:</span> <span class="token string">"$299"</span> <span class="token punctuation">}</span> <span class="token punctuation">]</span> |
Now, in the following section we need to show the delivery options of the product and the expected delivery time in the product catalog. There are three possible solutions, each of which has its own problem to consider:
1 – Fetch data from another resource
GET / api / products /: id
1 2 3 4 5 6 7 8 9 10 | <span class="token punctuation">{</span> <span class="token property">"products"</span> <span class="token operator">:</span> <span class="token punctuation">{</span> ... <span class="token punctuation">,</span> <span class="token property">"delivery"</span> <span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"shipping"</span> <span class="token operator">:</span> <span class="token string">"Amazon Prime"</span> <span class="token punctuation">,</span> <span class="token property">"expectedDays"</span> <span class="token operator">:</span> <span class="token string">"2"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Problem: this way we might run into an under-fetching situation. To display delivery information, now you have to run two request servers instead of one. And if your requests change in the future, performance will suffer.
GraphQL: only run a single query
1 2 3 4 5 6 7 8 9 10 11 12 | query <span class="token punctuation">{</span> products <span class="token punctuation">{</span> title desc price delivery <span class="token punctuation">{</span> shipping expectedDays <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
2 – Modify existing resources to return products
GET / api / products
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <span class="token punctuation">[</span> <span class="token punctuation">{</span> ... <span class="token punctuation">,</span> <span class="token property">"delivery"</span> <span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"shipping"</span> <span class="token operator">:</span> <span class="token string">"Amazon Prime"</span> <span class="token punctuation">,</span> <span class="token property">"expectedDays"</span> <span class="token operator">:</span> <span class="token string">"2"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> ... <span class="token punctuation">,</span> <span class="token property">"delivery"</span> <span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"shipping"</span> <span class="token operator">:</span> <span class="token string">"Amazon FBA"</span> <span class="token punctuation">,</span> <span class="token property">"expectedDays"</span> <span class="token operator">:</span> <span class="token string">"6"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">]</span> |
Problem: this seems to be a pretty neat solution. However, if you are displaying product listings elsewhere on the store – for example, in widgets – and of course you’re over-fetching.
GraphQL: the client can just fetch the necessary data, regardless of the other. Therefore, it will prevent data from being over data.
1 2 3 4 5 6 7 8 | query <span class="token punctuation">{</span> products <span class="token punctuation">{</span> title desc price <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
3 – Create a new resource that returns the original product details along with the product code
GET / api / productsWithDeliveryDetails
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <span class="token punctuation">[</span> <span class="token punctuation">{</span> ... <span class="token punctuation">,</span> <span class="token property">"delivery"</span> <span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"shipping"</span> <span class="token operator">:</span> <span class="token string">"Amazon Prime"</span> <span class="token punctuation">,</span> <span class="token property">"expectedDays"</span> <span class="token operator">:</span> <span class="token string">"2"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> ... <span class="token punctuation">,</span> <span class="token property">"delivery"</span> <span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"shipping"</span> <span class="token operator">:</span> <span class="token string">"Amazon FBA"</span> <span class="token punctuation">,</span> <span class="token property">"expectedDays"</span> <span class="token operator">:</span> <span class="token string">"6"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">]</span> |
Problem: The main problem with this approach is that you have to define a new endpoint for each view you need to display on the front-end. This slows down UI development and makes it difficult to update UI.
GraphQL: With GraphQL, the client only needs to fetch exactly what it needs, so going back and performing UI updates shouldn’t be a problem. All you have to do is add a new field to the query.
1 2 3 4 5 6 7 8 9 10 11 12 | query <span class="token punctuation">{</span> products <span class="token punctuation">{</span> title desc price delivery <span class="token punctuation">{</span> shipping expectedDays <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Same
- Both GraphQL and REST are resource-based and can specify an ID for a resource.
- Fetch data over an HTTP request.
- Returns JSON data in the response
Different
- REST can cause over or under-fetching problems, while GraphQl doesn’t.
- The REST endpoint is the object’s identity, while the object’s ID has nothing to do with how you access it in GraphQL. In other words, in REST you define the object on the back-end and in GraphQL you “define” this object on the front-end.
- With REST, the server determines the shape and size of the resource while GraphQL, the server only needs to declare the available resources and the client can ask for exactly what it needs.
- REST automatically caching while GraphQL doesn’t have an automatic caching system.
- Error handling in REST is much simpler than GraphQL.
GraphQL and REST are simply two ways to send data over HTTP. While GraphQL has many advantages over REST, it’s not always the best implementation.