GraphQL is a language that enables you to provide a complete and understandable description of the data in your API. Furthermore it gives clients the power to ask for exactly what they need and nothing more. The project’s website can be found at http://graphql.org/.
There are several advantages of GraphQL.
GraphQL is declarative: Query responses are decided by the client rather than the server. A GraphQL query returns exactly what a client asks for and no more.
GraphQL is compositional: A GraphQL query itself is a hierarchical set of fields. The query is shaped just like the data it returns. It is a natural way for product engineers to describe data requirements.
GraphQL is strongly-typed: A GraphQL query can be ensured to be valid within a GraphQL type system at development time allowing the server to make guarantees about the response. This makes it easier to build high-quality client tools
In this tutorial you’ll learn how to setup a GraphQL server with Node.js and Express. We’ll be using the Express middleware express-graphql in our example. Furthermore you’ll learn how to use GraphQL on the client side to send queries and mutations to the server.
Setting Up The Project
To setup a GraphQL Node.js server let’s start with creating a new empty project folder first:
$ mkdir gql-server
Change into that directory and initiate a new package.json file by executing the following NPM command:
$ npm init
Furthermore create a new server.js file in the project directory. That will be the file where the code required to implement the Node.js GraphQL server will be inserted in the next section:
$ touch server.js
Finally make sure that NPM packages graphql, express and express-graphql are added to the project:
$ npm install graphql express express-graphql —save
Creating A Basic GraphQL Server With Express
Now that the Project setup is ready let’s create the a first server implementation by inserting the following JS code in server.js:
var express = require('express');
var express_graphql = require('express-graphql');
var { buildSchema } = require('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'));
To create the schema we’re calling the function and passing in a string that contains the IDL (GraphQL Interface Definition Language) code which is used to describe the schema. A GraphQL schema is used to describe the complete APIs type system. It includes the complete set of data and defines how a client can access that data. Each time the client makes an API call, the call is validated against the schema. Only if the validation is successful the action is executed. Otherwise an error is returned.
Finally the Express server is created with a GraphQL endpoint: /graphql. To create the GraphQL endpoint first a new express instance is stored in app. Next the app.use method is called and two parameters are provided:
The three configuration properties which are used for the Express GraphQL middleware are the following:
The Node.js server can be started by executing the following command in the project directory:
$ node server.js
Having started the server process you should be able to see the output
Express GraphQL Server Now Running On localhost:4000/graphql

In the query editor type in the following code:
{
message
}
Next hit the Execute Query button and you should be able to see the following result:

Implementing A More Sophisticated Example:
Now that you have a basic understanding of how to implement a GraphQL server with Node.js and Express, let’s continue with a more sophisticated example. Add a new JS file to the project:
$ touch server2.js
Next let’s add the following implementation:
var express = require('express');
var express_graphql = require('express-graphql');
var { buildSchema } = require('graphql');
// GraphQL schema
var schema = buildSchema(`
type Query {
course(id: Int!): Course
courses(topic: String): [Course]
},
type Course {
id: Int
title: String
author: String
description: String
topic: String
url: String
}
`);
var coursesData = [
{
id: 1,
title: 'The Complete Node.js Developer Course',
author: 'Bharat Bhushan Designmycodes',
description: 'Learn Node.js by building real-world applications with Node, Express, MongoDB, Mocha, and more!',
topic: 'Node.js',
url: 'https://www.designmycodes.com/node/develop-nodejs-and-mongodb-apps-with-mongoose.html'
},
{
id: 2,
title: 'Node.js, Express & MongoDB Dev to Deployment',
author: 'Bharat Bhushan',
description: 'Learn by example building & deploying real-world Node.js applications from absolute scratch',
topic: 'Node.js',
url: 'https://www.designmycodes.com/node/create-app-with-react-and-node.html'
},
{
id: 3,
title: 'JavaScript: Understanding The Weird Parts',
author: 'Bharat Bhushan',
description: 'An advanced JavaScript course for everyone! Scope, closures, prototypes, this, build your own framework, and more.',
topic: 'JavaScript',
url: 'https://www.designmycodes.com/node/different-ways-of-async-patterns-in-nodejs.html'
}
]
var getCourse = function(args) {
var id = args.id;
return coursesData.filter(course => {
return course.id == id;
})[0];
}
var getCourses = function(args) {
if (args.topic) {
var topic = args.topic;
return coursesData.filter(course => course.topic === topic);
} else {
return coursesData;
}
}
var root = {
course: getCourse,
courses: getCourses
};
// 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'));
Ok, let’s examine the code step by step. First we’re defining a schema which now consists of a custom type Course and two query actions.
To be able to return data without the need to connect to a database we’re defining the coursesData array with some dummy course data inside.
In the root resolver we’re connecting the course query action to the getCourse function and the courses query action to the getCourses function.
Accessing The GraphQL API
Now let’s start the Node.js server process again and execute the code from file server2.js with the following command:
$ node server2.js
If you’re opening up URL localhost:4000/graphql in the browser you should be able to see the GraphiQL web interface, so that you can start typing in queries. First let’s retrieve one single course from our GraphQL endpoint. Insert the following query code:
query getSingleCourse($courseID: Int!) {
course(id: $courseID) {
title
author
description
topic
url
}
}
The getSingleCourse query operation is expecting to get one parameter: $courseID of type Int. By usign the exclamation mark we’re specifying that this parameters needs to be provided.
Within the getSingleCourse we’re executing the course query and for this specific ID. We’re specifying that we’d like to retrieve title, author, description, topic and url of that that specific course.
{
"courseID":1
}
Click on the execute button and you should be able to see result:
Using Aliases & Fragments
You’re able to include multiple queries in one query operation. In the following example the getCourseWithFragments query operations contains two queries for single courses. To distinguish between both queries we’re assigning aliases: course1 and course2.
query getCourseWithFragments($courseID1: Int!, $courseID2: Int!) {
course1: course(id: $courseID1) {
...courseFields
},
course2: course(id: $courseID2) {
...courseFields
}
}
fragment courseFields on Course {
title
author
description
topic
url
}
As you can see the query operations requires two parameters: courseID1 and courseID2. The first ID is used for the first query and the second ID is used for the second query.
Another feature which is used is a fragment. By using a fragment we’re able to avoid repeating the same set of fields in multiple queries. Instead we’re defining a reusable fragment with name courseFields and specific which fields are relevent for both queries in one place.
Before executing the query operation we need to assign values to the parameters:
{
"courseID1":1,
"courseID2":2
}
Creating And Using Mutations
So far we’ve only seen examples which fetches data from our GraphQL server. With GraphQL we’re also able to modify data. by using Mutations. To be able to use a mutation with out GraphQL server we first need to add code to our server implementation in server2.js:
// GraphQL schema
var schema = buildSchema(`
type Query {
course(id: Int!): Course
courses(topic: String): [Course]
},
type Mutation {
updateCourseTopic(id: Int!, topic: String!): Course
}
type Course {
id: Int
title: String
author: String
description: String
topic: String
url: String
}
`);
Here you can see the schema is now containing a Mutation type as well. The mutation which is defined is named updateCourseTopic and takes two mandatory parameter: id and topic. The return type of that mutation is Course.
Using that mutation it should be possible to change the topic of a specific course. In the same way like we did it before for queries we’re now assigning a function to the mutation in the root resolver. The function is implemented with the corresponding update logic:
var updateCourseTopic = function({id, topic}) {
coursesData.map(course => {
if (course.id === id) {
course.topic = topic;
return course;
}
});
return coursesData.filter(course => course.id === id) [0];
}
var root = {
course: getCourse,
courses: getCourses,
updateCourseTopic: updateCourseTopic
};
Now the sever is able to handle mutations as well, so let’s try it out in the GraphiQL browser interface again.
A mutation operation is defined by using the mutation keyword followed by the name of the mutation operation. In the following example the updateCourseTopic mutation is included in the operation and again we’re making use of the courseFields fragment.
mutation updateCourseTopic($id: Int!, $topic: String!) {
updateCourseTopic(id: $id, topic: $topic) {
... courseFields
}
}
The mutation operation is using two dynamic variables so we need to assign the values in the query variables input field as follows:
{
"id": 1,
"topic": "JavaScript"
}
By executing this mutation we’re changing the value of the topic property for the course data set with ID 1 from Node.js to JavaScript. As a result we’re getting back the changed course:
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.
Comments
Post a Comment