My second attempt at GraphQL

Rotimi Babalola
Backticks & Tildes
Published in
6 min readAug 9, 2017
GraphQL — a new adventure

I remember the first time I tried to learn GraphQL. I needed to learn it in order to complete a task for my 2nd team project in Andela and I was in such a hurry to finish my tasks that I wasn’t able to experience how awesome GraphQL was.

About 2 months later, I had some free time on my hands and I decided to go back to GraphQL to try it out again. My experiences and learnings from my second attempt at GraphQL is what I’ll be sharing in this article.

By now you may have heard the comparisons between GraphQL and REST APIs. For me, the major difference between the two is that in REST APIs the shape and size of the data is determined solely by the server while for GraphQL APIs, the client has control over the shape and size of the data it receives. Another key difference is that REST APIs usually have multiple endpoints that the client can use to access the server’s resources whereas with GraphQL all the server’s resources are exposed via a single endpoint. (Yes, you read this right) 😎

Let’s say you’re building a document management application. The application allows its users to manage their documents (duh 🙄). If you wanted to get information about a user and the documents owned by that user with a REST API, here is what that would look like. First, you’d have to get the users information so you’d have something like:

GET /users/1{
"firstName": "John",
"lastName": "Doe",
"email": "johndoe@email.com",
... // more fields here
}

Next, you need to get the data about the documents owned by that user which might look like:

GET /documents/user/1{
values: [
{
"title": "Some title",
"text": "Some text",
"access": "Public",
... // more fields here
},
{
... // other documents here
}
]
}

Alternatively, we could create a custom endpoint for this purpose e.g.

GET /user/documents/1

This solution works but what if we want to add extra functionality to our app? Say we want to show a user the title of all her private documents. We would need to either do some client-side logic to filter for only private documents or create another endpoint that will retrieve the title of only private documents (that belong to that user) from the server. This might look like

GET /user/documents/1/title

Now you see the problem, as the needs of the client grow we would need to add more and more custom endpoints to keep up. Note that we could potentially over-fetch data from the server. We want only the title of private documents but we’re getting fields like text and access with our response. This can be avoided if we created a custom endpoint to retrieve only the titles of private documents.

Wouldn’t it be cool if the client had a way to tell the server exactly what it needs without having to add custom endpoints? Wouldn’t it also be cool if we could also avoid potentially over-fetching data as this could slow down our application. This is where GraphQL comes to the rescue 😎.

What is GraphQL?

Let’s look at the definition from its website, I couldn’t have explained it any better.

GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.

Let’s revisit the document management application from a GraphQL perspective; which will help us understand the explanation better.

With GraphQL the query to get the title of only private documents for a user would look like:

type Query {
Documents(userId: 1, access: "Private") {
title
}
}

This is what the response would look like:

 {
title: "Some title"
}

In order to explain this query I need to do some groundwork. First, I need to explain the concept of a GraphQL schema. You can think of a schema as a general description of the data which you are expecting from the server for a type. The schema also describes the relationship of a schema with other schemas. For example, the User schema will contain the fields that we can access for any user e.g. firstName, email etc. and a documents field which will be a reference to the Document schema.

Let’s see how we create a schema for the User type.

type User {
id: ID!
firstName: String
lastName: String
email: String
documents: [Document]
}

The User schema states the fields that are available for the User type, together with the scalar types for each. For example, firstName ,lastName and email are of type String; id is of type ID , the ! after the ID means this field cannot be null in the response. The documents field is of type Document which is a reference to the Document schema. Notice that it is enclosed in [] — this means it’s an array of documents. Here is the Document schema:

type Document {
id: ID!
title: String
text: String
access: String
owner: User
}

The same thing applies here too, also note that the owner field is of type User which references the User schema.

Cool isn’t it ? We just specify what we need and we get exactly that. Suppose we also need the text field in addition to the title we simply update our query like this:

type Query {
Documents(userId: 1, access: "Private") {
text
title
}
}

No need to add an extra endpoint or add any client side logic. This is fun isn’t it ?! 💃 Let’s do one more. Assume we want the emails of all users and the title and text of documents that they own, how do we get that ?

type Query {
User {
email
documents {
title
text
}
}
}

And if we want any extra fields we can just add it to our query.

The cool thing about this is that we get all the data from one endpoint and if we want to add more fields that the client can access we simply update the schema and we are good to go.

Summary

GraphQL is awesome and in this article we’ve seen how it how allows the client to specify the shape and size of the data it needs without having to create extra endpoints and we also avoided over-fetching data in the process. One of the major reasons I love GraphQL is because it allows me to think about data in a structured way. I don’t think of my data in terms of endpoints; I think of it as a graph and I use GraphQL to traverse the graph till I get what I want.

GraphQL also solves the problem of versioning APIs. With GraphQL we can avoid it all together. We simply add new fields to our schema and keep the former fields intact. Our API doesn’t need to have different versions — it simply grows.

Pretty awesome right ? Yeah I think so.

This article is just a high level intro to GraphQL, in my next post I will show you how to create a simple GraphQL server for our document management application. Hope to see you there!

If you like this article please click the 👏 below so others can read it. If you have questions or feedback about this article feel free to leave your thoughts in the comments section.

Thanks.

--

--