GraphQL

GraphQL with Node JS and Express JS

GraphQL is a query language for APIs and a runtime for fulfilling those queries with existing data. Here we are going to create a basic GraphQL Server With Node.js And Express

Setting up the project

To setup GraphQL server with Node JS and Express, let’s first create our project folder

$ mkdir graphql-server

Now navigate to the project folder we created and initiate new package.json file with following npm command assuming that you have already installed Node JS in your system. npm is the node package manager used to install various dependenccies and frameworks on to our project.

$ cd graphql-server
$ npm init

Follow the then instructions and a new file called package.json will be created in our project folder. Then after create a new file called server.js in the project directory where we will write the code to implement GraphQL server.

$ touch server.js

Now before starting to code, we will first import the packages that are required for our project.

$ npm install graphql express express-graphql --save

Creating GraphQL server with Express

In server.js let’s first import the dependencies required to create our server

import express from 'express'

import and export syntax are ES6 syntax that is not currently supported by Node JS. So that will give us error if we try to run this file.

$ node server.js

Babel

So we need to use an alternative JS compiler to compile this ES6 syntax. For this we will use babel. To use babel, we first need to install babel dependencies and follow other instruction as given in the babel website.

$ npm install --save-dev babel-cli babel-preset-env

Then create a file .babelrc with the following content in project root

{
    "presets":["env"]
}

After installing babel dependencies, finally we need to tell babel to compile the our ES6 syntax code we used so that we can use express framework. We can do that by adding a script in package.json with key build and value babel-node server.js

"script":{
    "build":"babel-node server.js"
}

babel-node server.js is triggered whenever we run the script named build

$ node run build

After sucessfully importing dependencies, we will create an instance of express server.

const server = express()
server.listen(4000,() => console.log("listening on port 4000"))

Not let’s start our server by running following command in out terminal inside our project folder.

$ node run build

We will get log as listening on port 4000 in our terminal if everything goes well which means our express server is up and running.

Now we have our express server ready, instead of having express to directly handle the requests made by the client, we want express to hand over that request to GraphQL and let GraphQL take care of it. OnceGraphQL has done its job, its going to give back the response to express and express will ultimately return back the response to the user.

Express and GraphQL are different entities and to make them work together, we need a bridge layer to make them work together. And express-graphql will do that for us.

import express_graphql from 'express-graphql'
import {buildSchema} from 'graphql'

Now we need to define an endpoint to be able access GraphQL. For that, in server.js,

server.use('/graphql', express_graphql({
    schema: schema,
    rootValue: root,
    graphiql: true
}));

Any request made to /graphql is be handed over to express-graphql.

server.use method takes two parameters

  1. URL endpoint as string
  2. Result of express_graphql function containing three properties
    • schema: GraphQL schema describes the complete APIs type system that includes the complete set of data and defines how a client can access that data. Each API call is validated against the schema.
    • rootValue: Root resolver object. Resolver contains the mapping of actions to functions.
    • graphiql: To enable the GraphiQL tool when accessing the endpoint via browser. GraphiQL is a graphical interactive in-browser GraphQL IDE. Via this tool, we can directly write our queries in the browser and try out the endpoint.

We will define schema and resolver as follows to test our GraphQL server

// GraphQL schema
var schema = buildSchema(`
    type Query {
        message: String
    }
`);
// Root resolver
var root = {
    message: () => 'Hello World!'
};

Final server.js script looks like below

import express from 'express'
import express_graphql from 'express-graphql'
import {buildSchema} from 'graphql'
// GraphQL schema
var schema = buildSchema(`
    type Query {
        message: String
    }
`);
// Root resolver
var root = {
    message: () => 'Hello World!'
};
// Create an express server and a GraphQL endpoint
var app = express();
app.use('/graphql', express_graphql({
    schema: schema,
    rootValue: root,
    graphiql: true
}));
app.listen(4000, () => console.log('Express GraphQL Server Now Running On localhost:4000/graphql'));

Now to test out the server, we can run our server script as

$ npm run build

Then when access localhost:4000/graphql in the browser, we are presented with a GraphiQL interface where we can write our queries to test out the endpoint.

In the query editor, write the following code:

{
    message
}

Then hit Execute Query button and you should be albe to see the folowing response:

{
    "data":	{
        "message":"Hello World!"
    }
}

Note

Every time we make any changes to our project, we have to save our project and re-run our script i.e. npm run build

What if we have to run the script only once and don’t need to re-run our script after every change we made to our project? The script runs automatically every time we save our changes to the project. We can accomplish this with babel-watch.

$ npm install --save babel-watch

Now in package.json, we change build script to babel-watch server.js instead of babel-node server.js

"scripts":{
	"test": "echo \"Error: no test specified\" && exit 1",
    "build": "babel-watch server.js"
}

Now we will run our script once and the script will run automatically every time we save our changes to the project