JS Monday 12 - Building a GraphQL Server

Remember the good old SOAP protocol? Maybe you forgot it ’cause REST replaced it, and it’s way better!
But what if I tell you that we’ll soon wish to forget REST in favor of GraphQL?

The need for querying data

GraphQL is a query language created by Facebook in 2012 and open sourced in 2015.
It allows requests and manipulations for specific data, so clients have more control over what information the server will send.
A common REST problem is Data Overfetching: imagine you only want to know the first name and the email of a given user, but the API will return the entire profile… why do we get so many useless informations?
Now imagine that you only need a list of user IDs, but the API will return a huge array of objects containing every user’s informations. What a waste of time and resources!
GraphQL provides a declarative data fetching API, which allows you to require only what you need.

Type Safety

GraphQL queries are written in the Schema Definition Language (SDL), which requires strong typing. GraphQL schemas are validated during compile time, which means that the compilation will fail if any type error is found in your schema.

Deprecation and Versioning

Coming from REST, you may remember that after some time, some APIs can be deprecated.
You may need to switch from https://someapi.dev/v1/myendpoint to https://someapi.dev/v2/myNewEndpoint ’cause the structure of our resources has changed over time.
GraphQL avoids that ’cause the client is querying the API, just like he would do on a database.
The structure may change on the server, but the client still will be able to get it contents in the desired format.

Creating the Server

So let’s build a GraphQL server! First of all, create a new project and install the following packages:

Great. Now let’s create a ./src/main.js file and build a new Express Server:

Let’s try to run our webserver and see if it works: node ./src/main.js:

Not the best looking web page, but it works! Now we may want to add a GraphQL endpoint, maybe using the awesome GraphiQL tool.

Let’s analyze what we did:

  • We imported the Express GraphQL middleware (express-graphql).
  • We imported buildSchema function, which allow us to build a GraphQL Schema which describes our source data.
  • On line 7, we build our Schema using the Schema Definition Language (SDL). We’ll have to define a type for each value (in that case, we just have message, which is String).
  • On line 13, we define a Resolver: it contains the mapping of actions to functions. When you’ll require the message data, our resolver will just send back the hello world string. Pretty easy, isn’t it?
  • On line 19 we finally create the /graphql endpoint, which also uses express-graphql middleware to create a GraphiQL interface.

Let’s start again our server and go to http://localhost:3000/graphql:

Awesome! With just few lines of code, we created a GraphQL endpoint! Let’s test it requiring our message:

And here you are! We just made our first GraphQL server!
Now let’s do something more complex. Let’s create a new file ./src/data.js:

Ok, now we have our little dataset! We’ll expose a GraphQL endpoint which will allow us to query against a list of programming languages.

In order to make the code more maintainable, let’s create a third file: ./src/graphqlData.js

First of all: let’s importo both our data and buildSchema.
We need to define a schema for our GraphQL endpoint. As you can see, we first define the Query type, which allows us to:

  1. Get a specific language, given an ID (which is an Integer). It will return a Language, which is a type that we’re gonna create in the lines below.
  2. Get a list (array in JavaScript) of languages, given a specific paradigm. Again, a paradigm needs to be of type String, and will return a list (again, array in JavaScript) of Language.

Last but not least, we define the Language type. Coming from other programming languages, it feels like writing down a struct or a record.
When we define a new GraphQL type, we need to write a description of the data that will be queried. In our case, we have an id which is an Int, a name which is a String and so on.

Let’s move on and create two functions which will allow us to get our data:

We just created two functions and a constant value, let’s see how they works:

  • getLanguage accepts an Object as argument, and will filter our data returning us just the language with a given ID.
  • getLanguages accepts an Object as argument, and will return an array of languages given a specific paradigm.
  • rootValue just composes our rootValue to be used in express-graphql.

Please note that both getLanguage and getLanguages returns the same type we defined in our schema.

Now put everything together:

Awesome! Let’s modify a bit our ./src/main.js file:

And now it’s time to test it out! Let’s restart our webserver and test our GraphQL endpoint:

Awesome! And what if we want to remove some values from our query?

Sooooo easy!
What if we want to get a specific language?

We did it! We created a simple GraphQL endpoint in just a few lines of code.
Greatest thing is that our data could come from a database, a file, wherever we wish!
This is just a simple implementation… but imagine how far we can go from here!

You can see the complete code here: