Running a GraphQL Server on NodeJS
The fundamental idea of a GraphQL API is that all API functionality is available via a unified query language, under a single endpoint. GraphQL is designed to make APIs fast, flexible, and developer-friendly.
GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.
What is GraphQL?
- Application layer query language
- Open sourced by Facebook in 2015
- Can be used with any type of database
- Ability to ask for exactly what you need and nothing more
- Get multiple resources in a single request
I will use the GraphiQL tool to interact with the GraphQL server. It's an interactive IDE which runs in the browser (provides syntax highlighting, error reporting, automation and hinting). GraphiQL helps us test all of our queries and mutations.
Building a GraphQL Server
I am going to use the CLI to setup my application. Therefore make sure you have NodeJS (>= 10.3.0) installed on your computer as well, if you wish to follow along. I'll create a new directory and issue the npm init command, which will create the package.json file:
// Creating a new directory and change into that directory
mkdir graphql-server
cd graphql-server
// Initializing our NodeJS project
npm init
package name: (graphql-server)
version: (1.0.0)
description: Simple GraphQL server
entry point: (index.js) server.js
test command:
git repository:
keywords:
author: Thabo Lebelo
license: (ISC)
Step 1: Install all required dependencies
Node Package Manager (npm) is needed to install the dependencies for our NodeJS application
npm install graphql express express-graphql nodemon
Step 2: Setup an express server
Create a server.js file in the root directory of the application code
const express = require('express');
const app = express();
app.listen(4000, () => {
console.log('Server is runnning at http://localhost:4000')
})
Let's create a script in the package.json file to start up our server
"dev-server": "nodemon server.js"
Open a terminal and run npm run dev-server
to start up our application, head to the browser on http://localhost:4000

Since our application doesn't have any routes, we get the above message. With our server, we will get one route to GraphQL. Let's update the server.js file to include this endpoint:
const express = require('express');
const expressGraphQL = require('express-graphql');
const schema = require('./schema.js')
const app = express();
app.use('/graphql', expressGraphQL({
schema: schema,
graphiql: true
}))
app.listen(4000, () => {
console.log('Server is runnning at http://localhost:4000')
})
Step 3: Create a Schema for the GraphQL API
Notice in the previous step we referenced a schema for our GraphQL server. The schema will define the queries and mutations for our API. Let's create schema.js file for our data types:
const {
GraphQLObjectType, GraphQLSchema,
GraphQLString, GraphQLList,
GraphQLInt, GraphQLNonNull
} = require('graphql')
In the same schema.js file, I will define a CustomerType
for our API, and hardcode some dummy data for now.
const customers = [
{ id: '1', name: 'John Doe', email: 'john@gmail.com', age: 35 },
{ id: '2', name: 'Steve Smith', email: 'steve@gmail.com', age: 25 },
{ id: '3', name: 'Sara Williams', email: 'sara@gmail.com', age: 32 }
];
const CustomerType = new GraphQLObjectType({
name: 'Customer',
fields: () => ({
id: { type: GraphQLString },
name: { type: GraphQLString },
email: { type: GraphQLString },
age: { type: GraphQLInt }
})
})
Now with the data object defined, I will create RootQuery
for fetching data. The root query is just a baseline for all other queries and object types for our API.
const RootQuery = new GraphQLObjectType({
name: 'RootQuery',
fields: {
customer: {
type: CustomerType,
args: {
id: { type: GraphQLString }
},
resolve(parentValue, args) {
for (let i = 0; i < customers.length; i++) {
if (customers[i].id == args.id) {
return customers[i]
}
}
}
},
customers: {
type: new GraphQLList(CustomerType),
resolve(parentValue, args) {
return customers;
}
}
}
});
module.exports = new GraphQLSchema({
query: RootQuery
});
Now to test the GraphQL API, start the server and open the browser on http://localhost:4000/graphql to get the GraphiQL IDE:



Step 4: Implement JSON Server and Axios
In the previous step, we used hardcoded data for the API, which is not realistic. Let's install JSON Server for a more realistic environment and Axios which is an HTTP client to make requests to the json server:
npm install json-server axios
I will add another script in the package.json file to start up the json server:
"json-server": "json-server --watch data.json"
Now let's add the data.json file to our application to host some customer information for the GraphQL API:
{
"customers": [
{
"id": "1",
"name": "John Doe",
"email": "john@gmail.com",
"age": 50
},
{
"id": "2",
"name": "Keith Wilson",
"email": "kieth@gmail.com",
"age": 50
},
{
"id": "3",
"name": "Tom Jones",
"email": "tom@gmail.com",
"age": 23
},
{
"id": "4",
"name": "Jen Thompson",
"email": "jen@gmail.com",
"age": 22
},
{
"id": "5",
"name": "Harry White",
"email": "harry@gmail.com",
"age": 3
}
]
}
Open a new terminal and run npm run json-server
to start up the JSON Server, head to the browser on http://localhost:3000.

Step 5: Modify the Schema to use live data
Let's update the schema.js file and update the RootQuery
to fetch data from our mock database. Comment out the "customers" hardcoded data object and make GET requests for customer data:
const RootQuery = new GraphQLObjectType({
name: 'RootQuery',
fields: {
customer: {
type: CustomerType,
args: {
id: { type: GraphQLString }
},
resolve(parentValue, args) {
return axios
.get(`http://localhost:3000/customers/${args.id}`)
.then(response => response.data)
}
},
customers: {
type: new GraphQLList(CustomerType),
resolve(parentValue, args) {
return axios
.get(`http://localhost:3000/customers`)
.then(response => response.data)
}
}
}
});
Step 6: Add mutations to the Schema to update data
Up to this point we can fetch individual customers and all customers, now I want to add, edit, and remove a customer. This will be done through mutations in our schema.js file:
const mutation = new GraphQLObjectType({
name: 'Mutation',
fields: {
addCustomer: {
type: CustomerType,
args: {
name: { type: new GraphQLNonNull(GraphQLString) },
email: { type: new GraphQLNonNull(GraphQLString) },
age: { type: new GraphQLNonNull(GraphQLInt) }
},
resolve(parentValue, args) {
return axios
.post(`http://localhost:3000/customers`, {
name: args.name,
email: args.email,
age: args.age
})
.then(response => response.data)
}
}
}
});
module.exports = new GraphQLSchema({
query: RootQuery,
mutation
});
Let's try do our mutation through the graphiql IDE tool. I will try add a customer to the database data.json file.

Now to verify that the customer data is indeed added to the database, open the data.json file:

I will add the rest of the mutations (edit and delete) to the schema.js file then test the mutations on graphiql:
editCustomer: {
type: CustomerType,
args: {
id: { type: new GraphQLNonNull(GraphQLString) },
name: { type: GraphQLString },
email: { type: GraphQLString },
age: { type: GraphQLInt }
},
resolve(parentValue, args) {
return axios
.patch(`http://localhost:3000/customers/${args.id}`, args)
.then(response => response.data)
}
}
deleteCustomer: {
type: CustomerType,
args: {
id: { type: new GraphQLNonNull(GraphQLString) }
},
resolve(parentValue, args) {
return axios
.delete(`http://localhost:3000/customers/${args.id}`)
.then(response => response.data)
}
}
Running the above mutations on graphiql returns the below results:


Summary
There you have it, we just created a GraphQL server running on NodeJS. I hope this was informative. Checkout the graphql-server repo on GitHub if you get stuck. We can do much more with GraphQL and my implementation was just scratching the surface.