GraphQL Overview — Part 1 — What is GraphQL?

Sebastian Rabiej
SoftwareMill Tech Blog
4 min readFeb 15, 2021

--

Photo by Jens Herrndorff on Unsplash

This article was co-authored by Łukasz Żuchowski, Kamil Kupczyński , and Piotr Jasiak.

Many years ago, people used to say that every road leads to Rome. Nowadays, we can say that every request leads to a single endpoint.

GraphQL is starting to get popular. According to the State of JavaScript, in 2016, 36.6% of respondents never heard of it, but in 2020, this number dropped to 2.3%.
It’s hard to be surprised. It gives users custom access to the data and a single API endpoint to make requests. Besides that, it provides an endpoint contract, so there is no need to use additional software like Swagger. There are easy-to-use and effective client libraries and tools along with good documentation. What not to love? Well… nothing is perfect but first things first.

What is GraphQL?

GraphQL is a query language for your API, and a server-side runtime for executing queries by using a type system you define for your data.

So GraphQL is an idea to provide a simple way of communication between client and server. The client knows about the server’s endpoint, the endpoint provides a schema. The schema defines the communication protocol, such as access methods, inputs, and outputs. Requests and responses are JSON documents that are compliant with the endpoint’s schema.
During request, it is validated with the schema, so a malformed request would be rejected by the server with a proper error message. It might remind you a bit of SOAP and XSD, but this time without the bloated XML format.

GraphQL describes three types of requests:

  • query — read access
  • mutation — write access
  • subscriptions — “push” notifications

Simple schema example

To create the schema, you will use their own simple language (“GraphQL schema language”). In the example, we will create an API for changing the name of the logged user, and we will be able to get some information about us as well.

It looks pretty simple, right? You can operate on a few primitive types: ID, String, Int, Float, Boolean. Or define your own (User). In Schema, it is possible to work with non-nullable values and collections.

How to check what the favorite movie of the logged user is? Create a query like that:

Note that:

  • awesomeQueryName — is the name that the client is giving to this specific query request. It’s useful for multi-query requests.
  • me — is the name of the query on the server-side and should match to defined in the schema.
  • favoriteMovie — is the request attribute of the query result. You may request for many of those e.g. name, favoriteMovie.

As a response, we get:

Changing state is very similar:

As a response, we get our new name.

Subscriptions

Subscription is the third type of operation in the GraphQL world. It is somewhat different from the other two as it doesn’t follow the typical request-response pattern. Here, after establishing some kind of connection, the server will push new messages to the connected clients. This is done typically with the WebSocket protocol, but Server-Side Events and HTTP Long polling are also an option. We’ll skip the process of setting up the network layer for subscriptions on the client, as different libraries prefer different approaches to the problem. See setup for:

Building upon the previous example — what if the User stores more than one movie, and we want to be notified whenever a change in the list of favorite movies occurs?

Let’s have a look at what such a subscription might look like:

Looks familiar, doesn’t it? The only change is in the operation name, subscription. After sending the message, you’ll have an open connection, and whenever something changes in the favoriteMovies, you’ll receive a message containing the updated array:

When should you use subscriptions? If your application needs real-time updates (think of chat apps etc.), or you are doing multiple, small, incremental updates to a big initial data structure, then they are probably the way to go.

Error Handling

Error handling in the GraphQL world is a bit different than in REST. Basically, all errors that arise while the GraphQL server is processing the request populate the error field of the response. In addition, it doesn’t matter whether the query succeeded or failed, GraphQL specification does not state anything about the response code the server should return. It is a common practice to always return HTTP 200 OK status. Sounds strange, doesn’t it? Well, it actually makes a lot of sense. In most cases, a GraphQL query contains requests for many resources. What if some of them get resolved and others not?

You can simply respond with proper data in the data field while replacing error-causing fields with null. Then, propagate error field with an array of errors, ideally giving a human-readable reason in the message field, location, that will point to the line and column of the query that caused problems, as well as path which corresponds to the field that couldn’t be resolved. Take a look at the example below:

Suppose that, for some reason, your service cannot fetch users, however, it is still able to get orders. Then, instead of failing, the GraphQL service may respond:

As you see, this approach gives much more flexibility and it wouldn’t be possible with just plain HTTP error codes.

Summary

GraphQL is a great idea to create an API, but simplicity often goes with some trade-offs. With GraphQL, we leave creating a request to our clients. This attitude may provide to the N+1 problem or other performance issues.
It’s a great tool, but there are no silver bullets.
In the next part of the series, we will talk about libraries to support GraphQL.

--

--