3 Reasons I Loved Learning GraphQl

Garrett Levine
Building CrowdRiff
Published in
8 min readAug 1, 2017
Photo by Steve Richey, provided by Unsplash.com

I have been working at CrowdRiff for a year and a half now and for the last 6 months I have been making a transition from front-end development towards back-end development.

Currently at CrowdRiff, we have a “middle-end” node server which serves as both a proxy server to micro services and layer for managing database interactions. This server uses the express framework with GraphQl library. Before working with this project I had built a handful of REST APIs, but I quickly fell in love with the flexibility, strict typing, and self documenting power of GraphQl.

What is GraphQl ? 🙃

GraphQl is a query language which is used instead of REST APIs which returns data based on a single POST endpoint. Instead of multiple endpoints and types of requests (GET/DELETE/PUT), GraphQl makes use of its own query language to interact with your API all through one route.

One of its benefits is the power it provides the front-end developer who might be requesting data from the server. The requester has the ability to specify the data being returned from the server. This means that there are less endpoints that need to be written, because the front-end specifies what data they want back from the request.

But how do you write a non-REST endpoint? Let’s explore!

Firstly, GraphQl brings to node.js the idea of typing your data. This means that you are telling GraphQl what a specific set of data is going to look like. Let’s take a look at what returning a user object might look like. To create a GraphQLObjectType it might look like this…

const {
GraphQLInt,
GraphQlString,
GraphQLObjectType,
GraphQLNonNull,
} = require('graphql/type');
const userType = new GraphQLObjectType({
name: 'User',
description: 'A user\'s information.',
fields: {
id: {
type: new GraphQLNonNull(GraphQLInt),
description: 'ID of the user.'
},
email: {
type: new GraphQLNonNull(GraphQLString),
description: 'Email of the user.',
},
},
});
module.exports = userType;
  • First we have to name this type that we are creating. We’ll name it User for simplicity. Names must also be unique.
  • Next we can write a description for what this data represents.
  • Lastly we specify what key/value pairs this data will have. We have two fields in this piece of data, that id and the email . We specify what the type of data will be, integer and string for id and email respectively.

We can utilize this type in a GraphQl query. In GraphQl there are queries (think GET) and mutations (think POST/PUT/DELETE).

A GraphQl query might look like…

const { GraphQLInt, GraphQLNonNull } = require('graphql/type');
const User = require('../models/user');
const userType = require('./userType')'const usersQuery = {
type: userType,
description: 'Retrieve a user based on an ID.',
args: {
userId: {
type: new GraphQLNonNull(GraphQLInt),
description: 'ID of the user that you want to retrieve.',
},
resolve: (root, params, context) => {
return User.findById(params.userId).then(user => {
return user;
});
},
}
module.exports = usersQuery;

A query is an object with a series of rules/information about what type of data to expect from a request, and what type of data to return when requested.

  • We need to define what type of data this query is going to return, and we’ll say that it will return the userType that we just wrote.
  • We can write a description about what this query does. This is used for a useful self-documenting tool called GraphiQl (which I will talk about later in this article).
  • When the front-end calls this query, we are saying they MUST pass in a userId as an argument, and it must be an integer. If the front-end provides us any other information besides what we require, GraphQl will reject the request for us telling the front-end that the userId must be an int and cannot be a string.
  • Lastly everything that we want to do once this query is hit gets placed in the resolve. In this example, we are making a request to the database using some kind of User model that we’ve created (in a different file we’ll pretend we’re familiar with), and then we are returning the information that we find. This returned data MUST look like the type we define — in this case, that userType we wrote previously.

The front-end can make a request to a query and request data depending on what they want by providing a query string. This is quite literally a string in the body of a POST request. For example:

query {
users(id: 1) {
email,
},
}

With the above code, let’s say we perform a users query on the API. We provide it the ID of of 1 (in the parentheses), and we say in the curly brackets following it that we want returned just the email of that user. If we wanted to, we could also add the id to be returned since that is a part of our userType that we’ve made.

Now that we have a brief understanding of GraphQl, let’s talk about why I like it, and why it’s good for new learners.

1. Flexibility 💃

GraphQl removes the need to write multiple end points for similar data. As previously mentioned, instead of creating an endpoint which returns various information about the user, you create one query which the front-end specifies the data they wanted returned, and everything is accessed by the one endpoint which accepts the query string.

What does this mean for you as a developer though? I personally found it meant less worrying about server architecture, and more worrying about managing and manipulating data. Moreover, it meant that if I made a mistake in a query I wrote I didn’t have to worry about making a change to the endpoint because the front-end requests what they need — and if something isn’t requested by the front end, it won’t be served to them.

This helps with removing the weight of planning for new learners. You can pivot quickly and make changes on the fly. This means that decisions feel less severe, and you have more room to explore and experiment with functionality and working the your data.

2. Strict Typing 🤖

I didn’t understand the idea of typing before I started working with GraphQl, and I especially didn’t understand why I might need it or why it would be useful. GraphQl is strictly typed, meaning that every piece of data coming in, and every piece of data being returned has to be a defined type.

To take our user example from earlier, we set the userType object to have a field an id with the type of an integer, an email with type of a string. These fields can only accept these values. This at first seemed like a huge hassle because I was used to the dynamic ‘flexibility’ of JavaScript. But after spending some time working with GraphQL’s typing, it forced me to really understand the data I was working with, and that led me to understanding and appreciating why it’s important to have consistent reliable data.

One of my favourite things about GraphQl is it checks input types for you, and handles throwing rejections/errors for you. For those who have written REST endpoint before, or even flexible functions, you start to run into concerns with the type of data that is being passed to the front end. An endpoint may be requiring an ID passed to it, but what if the front end passes an string? what if it passes a boolean? What if the front end tries to pass in an object literal? For each of these cases you will need to write a check, and then a response to this incorrect data. Writing GraphQl with it’s strict typing does all of this for you.

I will add that understanding the data I am working with, and understanding new datatypes (GraphQl has enum types and interface types) are concepts that exist in other programming languages. Because these are ideas coming from other languages, it’s almost like a gentle introduction to more advanced concepts that are common in more strict back-end web languages — like Elixir or Go.

3. Self Documentation 💅

GraphQl is self documenting. The description fields that you’ve seen in the example code isn’t just for posterity and completeness, but it has a function within the GraphQl ecosystem.

Image of the GraphiQl interface with our user query/type documentation

GraphQl comes paired with a tool called GraphiQl (read graph-👁-Ql). It is kind of like an interactive playground meets documentation for your API. In GraphiQl you can hit queries/mutations you create and see full documentation for them — including any types that you will receive back (for example, our user type). This documentation will make use of all the descriptions you provide while writing types and queries/mutations — so it’s important to be diligent and write them in full!

This allows for a lot of rapid changed to the API your making, and your front-end developers are able to work with the latest information — without any of your documentation falling behind your application. This saves a lot of time when you’re creating new end points and iterating on data/information. GraphiQl is an incredibly big draw for why I really enjoy working with GraphQl as a node library.

Write servers faster🏃

I’ve really enjoyed learning back-end server development with GraphQl because it feels less serious and more focused on the data you have, as opposed to ways that you’re interacting with the data. In GraphQl you define the data, and ways to interact with it — and the front-end/user can choose how they want to request that data themselves. Endpoints are less plentiful, and queries/mutations feel more flexible and focused. In addition there is a lot of sanitization of data that GraphQl manages for you and makes sure that the server is receiving the information that it is expecting.

Final Thoughts

Like with any library, GraphQl comes with a lot of rules and ways to do things. If your experience with web programming is only JavaScript or dynamic languages this might seem like a big hassle at the beginning. I think that all the rules are a great direction for a JavaScript library, because the rules that GraphQl implements moves a node server closer to other more serious web programming languages. I look forward to writing more GraphQl, and seeing how the ecosystem evolves as it continues to grow and become more mainstream in the JavaScript back-end community.

If you’re interesting in seeing a more hands-on example of GraphQL, take a look at my article on converting a REST endpoint to GraphQL!

--

--