First steps with GraphQL and Apollo Server

Fernando Ferreira
Betsson Group
Published in
8 min readMar 10, 2020

A practical guide to building your first GraphQL API running on Apollo Server and Express

If you have heard about GraphQL for a while and you are not sure what it is, in this article, we are going to see what all the fuss is about. So without further ado, let’s get to it.

What is GraphQL

From the official docs:

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. GraphQL isn’t tied to any specific database or storage engine and is instead backed by your existing code and data.

Image by Jesper O. Christensen

When you implement GraphQL on your API you have a single endpoint where the client submits queries against your data and they get what they need, nothing more nothing less. GraphQL is a new API standard developed by Facebook and initially released in 2015 with its stable version in 2018. It provides a more flexible way to interact with APIs when compared with traditional REST endpoints. But how flexible is that?

REST x GraphQL

Imagine that we are building a Twitter-like application that has the following interface for the user’s profile page:

In a typical REST API we would have 3 separate endpoints to get this information:

/users/:id to get the user information

/users/:id/tweets to get the user’s tweets

/users/:id/followers to get the user’s followers

In this scenario, we have a problem known as under-fetching, the client application would need to issue 3 different HTTP requests to get all the information needed. For the first request to get the user’s name and description, our API could return not only what we need but also more data that we don’t care about on this particular page. E.g. address, phone number, email, etc. This is what we call over-fetching. All this extra data would also be transferred, resulting in more bandwidth usage and processing time on the backend. This could be solved by having specific endpoints or being more explicit about the data required. However, this can quickly get out of hand and become a nightmare to maintain.

In GraphQL, the client decides which fields they need, and they must be specified, this results in a bigger request payload. Also, since all requests are POST requests, we have some challenges related to caching. In a REST API, the URL along with the vary header is used as a cache key, so if the server receives another request for the same URL within a time frame, the cache is served or the browser gets a local version without requesting the server again. To be able to cache in GraphQL, we also have to take into consideration the query as part of the cache key. This article goes into more detail about server caching. Another way you can cache is on the client, and for that, there is the Apollo Client that implements caching out of the box.

Some applications also implement a mix of GraphQL and REST, where some resources can still be served with REST while others can use GraphQL, this is usually real-time related stuff that would not make sense to be cached as they are updated quite often.

GraphQL Implementation

Let’s see how we can implement this as GraphQL API. Our API will be created with an express application running Apollo Server. Apollo Server is a library that will help us connect the GraphQL schema to an HTTP server in Node.

This code snippet is the main file that starts the server, there are comments on the important parts:

Schema Definition

Now let’s have a look at the schema definitions file. This file is simply a definition of what is available on the API.

The first two types are fairly straightforward, they just describe the fields that will be found in the User and Tweet objects. The exclamation mark means that the field is required. The third type is the query definition, it describes the queries and what they will return:

  • Users query: returns an array of users.
  • User query: returns a single user taking its id as a parameter.
  • Tweets query: returns an array of tweets for a user and it has an optional last parameter.
  • Followers query: returns an array of users.

The next important part that we are going to look at is the resolvers file. It contains functions that are based on the schema file we just saw. This is what connects the requests to the actual data. For simplicity, on this example, we are not using a real database but rather just connecting to local JSON files which contains the data. In a real application, a resolver function is connected to a database, like MySQL or MongoDB or even another API.

On the query object the first function reaches out to our fake database and returns a list of users, the second function returns a user with the id provided. The root parameter is not needed here we only care about the id. The last function gives a list of tweets for a particular user and if the “last” parameter is passed it will return a subset of the tweets. This means that we can request the last 3 tweets of the user with id 5 for example (provided that they are stored from oldest to newest).

GraphQL Playground

We have seen some examples and now let’s see how this works in action. Luckily GraphQL provides us with a sweet playground to test all of this. If we start our server and navigate to http://localhost:3000/graphql (Link to the repository at the end of this article). On the left, we write our queries and on the right, we can see the result of the query by clicking on the play button in the middle.

Here we can create a query to request the name and description of the user with id 1. If we then decide that we need the user’s email we can just add a new field to the query. Hopefully, now you see the power of GraphQL, we didn’t have to modify the server to get the email and that can be done with any other field.

We can do a similar thing to get the user’s tweets but now instead of having the id as a hardcoded value, we can create a named query with variables. Let’s see:

On the top left, there is a query. To create a named query we start with the query keyword and its name. The name can be anything you want but the convention is to have the name of the resource followed by the name “Query”. Based on the schema file, this query has two parameters, the userId and last which is the number of recent tweets we are requesting. Variables in GraphQL start with a dollar sign. On the bottom left corner, we can create a JSON object with the parameters for the query.

Now let’s check how we can update the resolvers file to get the followers of a user:

We have a query that follows the same structure of the schema, which is the user as a parent and the followers as a field. This resolver gets the ids of the user’s followers, finds each user and returns a list of users. Now let’s see how that looks on the GraphQL playground:

On this query, we request the user’s name and the name of each follower. If we look at the schema file again we can see a follower is also a user which means we can get the followers of the followers and keep going as deep as we want.

Do you want to have a taste of how powerful GraphQL is?

On this next query, we can go 3 levels down and request the name of followers of the followers of the followers of the user with id 1.

If needed, a limit can be set on the server to block abusive queries that can take a long time. More on that here: GraphQL resource limitations.

Front end example

So far we have seen the backend side of GraphQL and you may be wondering how one can request this from a front end application. Let’s take a look at an example where we use pure javascript with the browser Fetch API.

The first function takes two parameters, a query, and an optional variables object, then we create the request object and call fetch to get the response. As mentioned earlier, in GraphQL, all requests use the post method (GET can be used but is not common).

On the second function that is called from the HTML file, there is a query (like we saw before on the playground) and a variables object. After this, we can call the first function with the query and the variables and log it on the console.

The HTML file is as simple as this:

This was just a simple example, for more complex front end applications you can use the Apollo Client and integrate it with Angular, React, Vanilla JS and much more. The Apollo Client can also subscribe to real-time messages and update the client when a resource changes on the server.

Conclusion

GraphQL is a powerful standard and it is much more flexible than a traditional REST endpoint. In a world of rapidly evolving APIs that can be requested by any device which is capable of HTTP requests, this can be a great alternative. Another advantage is that you can integrate into your existing solution and migrate at your own pace. However, we barely scratched the surface and there is a lot more that you can do. Here are some external resources where you can explore and learn more.

External Resources

Git hub repository with the code for this article

Introduction to GraphQL (Official Documentation)

Apollo Server Documentation

Exploring GraphQL (Free course by Linux Foundation)

--

--