DEV Community

Cover image for GraphQL - What is it and what does it solve?
Julián Scialabba
Julián Scialabba

Posted on • Edited on

GraphQL - What is it and what does it solve?

When I read for the first time about GraphQL and the problems that it solves I went crazy. For that reason I want you to know about GraphQL.
In this post I will explain what GraphQL is and what was the motivation for its creation.

What is GraphQL?

GraphQL is a query language to build APIs. It was created by Facebook with the motivation to solve some problems that REST APIs were causing them. The Mobile Facebook team were having problems with REST that were affecting their app performance. They had to do multiple requests for a simple app page and they also had problems with overfetching data. For that reason, the app performance was being affected. Thus, they started to create a new query language in which a client can specify exactly what data it needs and receive it in a single request.

In 2015 Facebook released a specification of the language. The specification was highly adopted by the community and the same community has developed multiples client and backend implementations in differents languages: https://graphql.org/code/

Currently, GraphQL is being used by lots of different companies such as GitHub, Twitter, Airbnb, Atlassian, among others.

What does GraphQL solve?

In this section, I will explain some problems of REST that GraphQL solves. The motivation of GraphQL was solve these problems, so it is important to know them.

Multiple Request

Suppose we need some information to fill out a page. On this page, we want to show a list of posts with their related user and comments.

Using REST API

If we are using a REST API, we probably will have to make several requests to be able to have all the information required by the page:

// Get a list of posts - GET
curl https://jsonplaceholder.typicode.com/posts

// Get user of each post -> N request if you have N posts
curl https://jsonplaceholder.typicode.com/users/{post.userId}

// Get comments of each post -> M requests, if each post would have M comments
curl https://jsonplaceholder.typicode.com/comments/${post.comments[i].id}

In this example, we can see an important problem. For each post we have to do:

1- An extra request to fetch the user.

2- If a post has M comments, M request for fetch all comments.

So, considering that we fetch N posts and each post have M comments:

totalRequests = 1 (fetch posts)+ N (fetch user) + NM (fetch comments)
totalRequests = 1 + N + NM

For example, if in a simple page we have 20 posts and 3 comments for each post, in total we will doing 1 + 20 + 20 * 3 = 81 requests.

This problem between posts and comments is a known problem called N + 1 problem. This problem occurs when we fetch a simple resource (1 request) and also we have to do N requests more to fetch all the needed information.

You can tell me that with a refactor in the API this problem disappears. And that is true. If we create a new endpoint like:

curl https://jsonplaceholder.typicode.com/posts/1/comments

We only have to do a single request per post to fetch all its comments. Even better, if we send the comments inside the post resource we won't need an extra request.

However, we shouldn't change our backend according to our frontend needs. This is expensive and reduces our development speed.

Using GraphQL

GraphQL allows us to get all the data that we need in only ONE request. A GraphQL query to get the same information that the previous example:

{
 getPosts{
   id
   title
   body
   user {
     id
     username
     avatar
   }
   comments {
     id
     body
     author {
       id
       username
       avatar
     }
   }
 }
}

With this unique GraphQL query we will get a list of posts with all the needed information. And this is an important advantage over REST.

Underfetching and Overfetching

Following the example of the before section, suppose we need to fill out a page with a list of posts. On this page we have to show the title, user's username and tags of each post.

Using REST API

We have an endpoint in our API that returns a list of posts with the following data:

[
{
  id: '1',
  title: 'A title',
  userId: '1',
  tags: ['js', 'html'],
  likes: 12,
  body: 'Post body',
  image: 'An img'
}, 
{...}, 
{...}
]

In the new page we only need the title, user's username and tags of each post. So, we can see that we are underfetching and overfetching data. We are underfetching data because we will need to request other endpoint to fetch the user's username. And we are overfetching data because attributes like 'body', 'image' and 'likes' are not used in the page. This is a REST APIs problem because endpoints returns fixed data structure. So, when we hit an endpoint it return a fix data that may contain more o less information than we need.

Using GraphQL

GraphQL allows the client can specify exactly the data it needs. Thus, we won't have the problem of underfetching and overfetching data. An example query could be:

{
 getPosts{
   id
   title
   tags
   user {
     username
   }
 }
}

Then, with a single query, we will obtain the exact information that we need to avoid underfetching and overfetching data.

Frontend coupled with Backend

Suppose we are developing a new page in our app. When we are analyzing what data we need, we identify that we have to call several REST API endpoints to get all the data.

If we don't want to affect the performance of the app because of the multiples API requests, we may do some changes on the REST API endpoints or create a new endpoint that returns all the data that we need for the page with only one or few endpoints. This situation often happens with REST APIs and we usually have to decide whether to make changes to the API or adapt the frontend to the information provided by the API. And this is a problem because we are coupling our frontend and backend.

With GraphQL this problem disappears. The client can obtain the data that its needs in any page without changing anything in the backend. The only the client has to know is the Schema of the GraphQL API. The GraphQL Schema defines the data provided by the API and clients can consume that data as they want.

Lack of a contract between Frontend and Backend

REST defines how a client and a server can communicate but don't define anything about the data structure of the information exchanged between the client and server. The decision about the data structure is open and usually the backend decides how to send and receive information with the clients. In organized teams, frontend and backend teams can agree about the endpoints and data structure of the API. Anyway, it is not a characteristic of REST APIs but the well-organized teams. In a lot of other situations where we have to use an external REST API we don't know about the data structure until we start using the API.

GraphQL solves that using a strong type system to define the data structure and the information that can be consumed from our clients. All these definitions are written down in a Schema using the GraphQL Schema Definition Language (SDL). Here an example:

type Post {
  id: ID!
  title: String!
  body: String!
  user: User!
  comments: [Comment]
}

type Comment {
  id: ID!
  body: String!
  user: User!
}

type User {
  id: ID!
  username: String!
  avatar: String
}

type Query {
  getPosts: [Post]
  getUsers: [User]
}

This schema serves as a contract between the client and the server.

Once the GraphQL Schema is defined, then frontend and backend teams can work independently because it exists a contract between them. So, frontend team can mock the data following the Schema and develop the entire frontend app or web page. When the backend is ready, then frontend team can use the real GraphQL API.

API without documentation

REST doesn't force you to create documentation about the API. There are tools like Swagger that helps developers to create REST APIs documentation. However, it requires an extra effort for the developer to create and maintain it. For that reason there are a lot of REST APIs with no documentation or with outdated documentation.

Due to GraphQL uses a strong type system it is a documented language by definition. So, only creating our GraphQL Schema we are generating our API documentation. For example, here a gif with the documentation of the Schema defined above:

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/a1b53478-90e5-48f4-8b6a-f53e0743936d/graphql_documentation_(1).gif

Lack of API usage tracking

With REST the only we can track about how clients consume our API is how often each endpoint is called.

With GraphQL, as each client specifies exactly the information that they are interested in, we can understand what data is being used and what is not being used. Also, we can measure performance for each attribute requested and this provides crucial insights about the performance of your API.

Conclusion

We have seen what is GraphQL and the advantages of GraphQL over REST.

GraphQL is a powerful tool but it is not a silverbullet. Building an API REST can be simpler. So, if you don't care about the REST problems that I have mentioned in this post, REST is a good choice for your project.

Thanks for reading!

Alt Text

Top comments (3)

Collapse
 
anirudhrowjee profile image
Anirudh Rowjee

Very nice introduction! I'm definitely going to explore this topic more.

Collapse
 
ramanaditya profile image
Aditya Raman

Well written. I have personally started using GraphQL around a quarter before and feel like this is the best. Makes the lives of developers quite easy.

Collapse
 
noothan profile image
noothan

loved the way you explained with example.