Fanis Prodromou
  • Blog
  • About
  • Blog
  • About
Search by typing & pressing enter

YOUR CART

3/31/2019 Comments

GraphQL from REST perspective

Picture
A majority of web sites are SPAs, built either with Angular, Vue, React or any other framework. My personal preference is Angular but this is not the case of this topic :) 
Apart from the web sites, a lot of mobile applications are hybrid built with frameworks such as Ionic. 

All of them require a back-end system that handles the database calls, the heavy data processing/manipulation etc. How does the Client app (SPA or hybrid) communicates with the Server App (back-end)? I bet that the first thing that arises in your mind is the REST. And yup! You are right. This is not the only solution though. There are other solutions that you should consider. 
From the title of this post, you can imagine what the solution I am talking about is :). GraphQL. 

Let's see what this is and how we can use it. 

Server Communication - REST

When you have to build a REST API, you know that you have to respect the REST principles and implement certain verbs.
Those are: 
  • GET
  • POST
  • PUT
  • PATCH
  • DELETE
The GET is responsible to Read data from the data-store and return them via HTTP to the consumer.
The POST is responsible to Create data in the data-store.
The PUT is responsible to Update/Replace data in the data-store.
The PATCH is responsible to Update/Modify data in the data-store.
The 
DELETE is responsible to Delete data in the data-store.

If we had to categorize them, wouldn't it be safe to set them under Query and Mutate categories?
Well yes :) it would be safe. (glad you agree!)

Under Query we would have the GET verb and 
under Mutate we would have the POST, PUT, PATCH, DELETE verbs.

Think of it. When we perform a GET request, we query the data from the data-store. Whereas, we mutate the data for all the other verbs.

Server Communication - GraphQL

Having categorized the REST verbs under Query and Mutate let's see the two basic factors of GraphQL.
Queries and Mutations. I am sure you got it. Right? You can imagine what each one is responsible for. We will see more soon...

REST payloads

For the communication between the Front-End(client) and the Back-End(server) we need to have a contract. We need to have a schema. I use the term "payload" for this.

For the sake of this post we will use the following JSON structure  

    
In order to built this payload, we need to have the relevant objects/classes as well. 
​(the code is in TS)

    

GraphQL Types

When REST have payloads, the GraphQL have the Types. In order to depict the above payload in Types we have to have the following 

    
This notation it looks like JSON. But it's not. It's a GraphQL SDL (Schema Definition Language) which consists of Type and Fields (it has much more but we won't cover them here. We will see just the very basics) 

Types
In front of Project and Task we see the keyword type.  

Field
The field is consist of a name and a "data" type. "id: ID"

"Data" types
In GraphQL the data types are called scalar types. That's why I have the term data in quotes. The built-in scalar types are
  • ID
  • String
  • Int
  • Float
  • Boolean

Note that with exclamation mark (!) we set the required fields

REST endpoints/resources

How can the Client request for Projects from the Server? We have to implement the relevant endpoints

GET          → /projects
POST       → /projects
PUT          → /projects/:id
DELETE → /projects/:id
PATCH    → /projects/:id

Say, that we need to get the tasks of a specific project. We need to implement a sub-resource/endpoint

GET → /projects/:id/tasks
(and all other verbs)

What if we want to get only that tasks though? Oh yes! We have to implement another endpoint

GET → /tasks
(and all other verbs)

GraphQL resolvers


The REST implementation have the endpoints, whereas the GraphQL have the Resolvers. 

In order to follow the comparison between REST and GraphQL, think of Resolvers sort of what the controllers are in REST.

The communication between the Client and the Server is made only via one endpoint. I am using the Apollo Framework and by default this exposes the /graphql endpoint.
​
Having said that, how can the Client requests for Projects from the Server?

QUERY              → /graphql
MUTATION    → /graphql
​

Two major questions came in the surface!
  • How can the Client get data from the server?
  • How can the Server knows what kind of data to return, and when?

GraphQL Queries

The Client is responsible to query the data from the Server. And can change the query any time without having to change anything on the Server!

    
This is a legit query and we are asking for the fields "id" and "name" from the "Project", we ask for the relevant "Tasks" each "Project" has and we want to get only the "name" of each "Task". If we want more or less fields, we can do so

    
The second query won't return any Task and won't even send a query to DB. Cool ehh?

GraphQL Resolvers - Implementation

Let's see an implementation of the resolvers

    
By convention the Resolvers should be written under Query, Mutation or by scalar types. We can see here that we have Query.projects and Project.tasks
As I said earlier, the Resolvers are sort of the same with Controllers. 

The Queries are associated with the Resolvers 

In this example, the Query.projects executes a query to DB via mongoose and returns all the items. if you scroll up a bit, you will see that we have the name projects in the query. That projects is associated with the Query.projects.
The Client is responsible for WHAT
The Server is responsible the HOW

GraphQL query and the response

So far so good. What is the response of the query? No more than a simple JSON
This query...

    
returns...

    

Why is it called GraphQL? Where is the graph?

You might say that there is no reason to go with GraphQL as it seems to do similar things as REST does. Well, yes and no. In REST we can not query from the client and if we have a demanded view on the client side, we might need to send multiple requests to the server via REST. Multiple requests means roundtrips which is translated with performance issues.

The solution for the demanded view in GraphQL, is to built a graph and request what the client requires via a single request.

    
We asked for the "name" and "id" of a particular "Project", the fields "id" and "name" of the relevant "Tasks" and then we want to get the "Projects" that are associated with each "Task" and the "Tasks" that are associated with each "Project". 

This seems to be an exaggeration! Think that the response of the GraphQL is the view model of the client. As such, you can do your bindings without having a middle layer to manipulate the data and the schema

Problems and solutions

Problem: Multiple round-trips to server to get the data needed for the Client
Solution: Get all the data via a single query and have only one round-trip

Problem: The data transferred in the wire are way more than required 
Solution: The Client decides what data is required and not the server

Problem: The server Serializes  way more data than required 
Solution: The Client decides what data is required and hence the Serialization time is decreased

Conclusions

The GraphQL is relatively new to me. I hope I managed to help you understand the very basic concepts. As everything, requires study and experimentation. 

Each implementation have its cons and pros. The GraphQL seems to be very promising and there are very nice frameworks out there. It is not a panacea though!

If you have any question, please shoot it. I will be happy to try answer it for you
Comments
comments powered by Disqus

    Author

    I am an Angular GDE, content creator who loves sharing knowledge

    Follow @prodromouf
    View my profile on LinkedIn

    Tags

    All Angular Angularjs General Graphql Ionic Javascript .net Nodejs Typescript

Proudly powered by Weebly