Click here to Skip to main content
15,868,016 members
Articles / Web Development / Node.js

Exploring GraphQL with Node.js APIs

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
30 Mar 2022CPOL6 min read 4.6K   3  
How to implement a GraphQL server with Node.js and Express
In this article, we’ll walk through setting up a project, creating a simple GraphQL server, building a complex schema, and creating mutations.

GraphQL is a query language for application programming interfaces (APIs). In simple terms, it is a syntax to define the data structure you need.

We already have a REST API, so how is GraphQL different? Like REST API, GraphQL is a stateless, client-independent API for exchanging data. However, its advantage is higher flexibility.

REST API has some serious performance issues when it comes to customizing API calls. This normally affects your application’s mobile users by causing content to load slowly. This is normally due to the time it takes to return data that is of little or no use along with the requested data.

To fix the issue of longer load times, developers must define new endpoints for each data structure requested, or use request parameters, which may be confusing to the front-end developers while sending the request as they might miss passing the right request parameters or interchange the use of parameters. GraphQL solves this issue by having one single endpoint and a structure that allows requested data to be passed as queries.

REST API has a large user base, but GraphQL is gaining popularity. Because of its improved performance, some large companies — such as Shopify and GitHub — are starting to offer GraphQL APIs for developers.

In this article, we’ll show you how to implement a GraphQL server with Node.js and Express. We will walk through setting up a project, creating a simple GraphQL server, building a complex schema, and creating mutations. Here is the repository for the codebase we will use.

How GraphQL Works

Image 1

GraphQL only needs a single endpoint. This endpoint takes the query with data customizations as the request body, which can be dynamic according to the needs of the data requested.

Other than the one endpoint, we’ll send only one kind of request: a POST request to the ‘/graphql’ URL. That is because with POST requests, you can add a request body containing the query to perform all the other data manipulations.

Structure of a GraphQL Query

A typical GraphQL query has three parts: operation type, operation endpoint, and requested fields:

GraphQL
{
  *operation type* {
   	*endpoint* {
       	*requested fields*
    	}
   }
}

Operation type, in turn, has three types:

  • Query: Used to retrieve specific data. Acts like a "GET" request.
  • Mutation: Used to manipulate data. Acts like "POST", "PUT", "PATCH", or "DELETE".
  • Subscription: Used to set up a real-time connection via WebSockets.

That’s enough theory. Let's get our hands code dirty!

Project Setup

You can implement a GraphQL server with any web server programming language, like Java, Ruby, Python, and C#, to name a few.

For the purpose of this demonstration, I’ll use Node.js and Express to set up a GraphQL server. If you want to follow this article using Node.js, and if you haven’t installed it in your system, you can download it from the official Node.js website.

Open your desired command prompt and check if Node.js and NPM are properly installed using the commands below:

JavaScript
node -v
npm -v

If you see their respective version numbers, then they are successfully installed.

Create a new empty project folder with an appropriate name:

JavaScript
mkdir graphql-demo

Go to that directory and initiate your Node.js project by creating a ‘package.json’ file using the command:

JavaScript
npm init

Create a new server.js file in the project directory using the following commands:

For Windows:

JavaScript
type nul > server.js

For Mac and Linux:

JavaScript
touch server.js

Add the required NPM packages graphql, express, and express-graphql to the project using the command:

JavaScript
npm install graphql express express-graphql –save

Now that we have set up the project, we are ready to implement our first GraphQL server.

Creating a Simple GraphQL Server

To handle a GraphQL query, we need a schema that defines the operation type and the API endpoint. We also need a resolver to map to the endpoint from the request. Here’s how a simple "Hello World!" program using GraphQL without an Express server looks:

GraphQL
var { graphql, buildSchema } = require('graphql');
 // Construct a schema, using GraphQL schema language
var schema = buildSchema(`
  type Query {
    hello: String
  }
`);
 // The root provides a resolver function for each API endpoint
var root = {
  hello: () => {
    return 'Hello world!';
  },
};
 // Run the GraphQL query '{ hello }' and print out the response
graphql(schema, '{ hello }', root).then((response) => {
  console.log(response);
});

The schema defines how the client can access the data. It gets validated on each API call and returns the data only if the validation is successful, else it returns an error.

The resolver consists of mapping actions to the endpoints defined in the query. As the query grows, the resolver will also grow.

Run the following command to see the GraphQL response:

JavaScript
node server.js

If you get the following response, you just ran your first GraphQL query:

JavaScript
{data: { hello: ‘Hello world!’} }

Let’s try the same program as above, but this time, let’s spin up an Express server. Change your server.js code to the following code:

GraphQL
var express = require('express');
var { graphqlHTTP } = require('express-graphql');
var { buildSchema } = require('graphql');
// Construct a schema, using GraphQL schema language
var schema = buildSchema(`
  type Query {
    hello: String
  }
`);
 // The root provides a resolver function for each API endpoint
var root = {
  hello: () => {
    return 'Hello world!';
  },
};
 var app = express();
app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: root,
  graphiql: true,
}));
app.listen(4000);
console.log('Running a GraphQL API server at http://localhost:4000/graphql');

Express spins up a server with GraphQL and with ‘graphiql’ set to ‘true’. It then opens an interactive graphical interface for trying out GraphQL queries. Bring up the server using the command:

JavaScript
node server.js

Open your desired browser and navigate to http://localhost:4000/graphql. You’ll be able to see an interface that lets you enter queries:

Image 2

Congratulations — you just executed a GraphQL query using an Express server!

Building a Complex Schema

Let’s update the schema for sample data like below:

GraphQL
var heroes = [
  {
    id: 1,
    name: 'Iron Man',
    age: '40',
    ability: 'Flying, Rockets'
  },
  {
    id: 2,
    name: 'Dr. Strange',
    age: '30',
    ability: 'Magic'
  },
  {
    id: 3,
    name: 'Hulk',
    age: '45',
    ability: 'Anger'
  },
  {
    id: 4,
    name: 'Ant man',
    age: '26',
    ability: 'Shrink'
  },
  {
    id: 5,
    name: 'Black Widow',
    age: '25',
    ability: 'Spy'
  }
];

In addition to using the primitive types, like integer and string, we can also define our own type and use it for other query parameters:

GraphQL
var schema = buildSchema(`
  type Query {
    hero(id: Int!): Person
  },
  type Person {
    id: Int
    name: String
    age: Int
    ability: String
  }
`);

Here, ‘Person’ is a user-defined type for the parameter ‘hero’. We have to update the resolver like below:

GraphQL
var root = {
  hero: getHero,  // Resolver function to return hero with specific id
};

Let’s spin up the server again using the command:

JavaScript
node server.js

Navigate to http://localhost:4000/graphql and enter the following query:

GraphQL
query getHero($heroId: Int!) {
    hero(id: $heroId) {
      id
      name
      age
      ability
    }
}

If you run the query, you’ll get the following error:

GraphQL
{
    "errors": [
    {
        "message": "Variable /"$heroId\" of required type \"Int!\" was not provided.",
        "locations": [
        {
            "line": 1,
            "column": 15
        }]
    }]
}

As the error states, we are missing the variable $heroId. Let’s quickly create a variable by clicking the Query Variables tab at the bottom left corner of the GraphQL interface.

Now, if you press run again, you can see the response data of that particular hero whose id we passed as a parameter:

Image 3

Using Mutations

We have seen how to retrieve data using GraphQL. Now, let’s see how to update data by using another operator type called mutations.

Update the build schema by defining a mutation:

GraphQL
var schema = buildSchema(`
  type Query {
    hero(id: Int!): Person
  },
  type Person {
    id: Int
    name: String
    age: Int
    ability: String
  }
  type Mutation {
    updateHero(id: Int!, name: String!, ability: String): Person
  }
`); 

We can see the mutation takes three parameters: ‘id’, ‘name’, and ‘ability’, and returns data of type ‘Person’. We also have to create a new function to update the data. We also need to update the resolver to point to that function:

GraphQL
// Updates a hero and returns new hero details
var updateHero = function ({ id, name, ability }) {
  heros.map(hero => {
    if (hero.id === id) {
      hero.name = name;
      hero.age = ability;
      return hero;
    }
  });
  return heros.filter(hero => hero.id === id)[0];
}
 
// Root resolver
var root = {
  hero: getHero,  // Resolver function to return hero with specific id
  updateHero: updateHero
};

Let’s run the server file again using:

JavaScript
node server.js

Navigate to http://localhost:4000/graphql and enter the following query:

GraphQL
mutation updateHero($id: Int!, $name: String!, $ability: String) {
  updateHero(id: $id, name:$name, ability: $ability){
  	name
 	 ability
  }
}

Also, define the required parameters in the Query Variables section:

GraphQL
{
  "id": 1,
  "name": "Captain America",
  "ability": "Shield"
}

Click run. We can now see the updated ‘hero’ data:

GraphQL
{
    "data": {
        "updateHero": {
            "name": "Captain America",
            "

Voila! You just updated your data using GraphQL.

How to Reduce Load Times in Your Own Application

GraphQL empowers developers to ask for exactly what they need and nothing more. This helps trim unwanted API calls, in turn reducing application load times.

Though REST API outmatches GraphQL due to market popularity, GraphQL is gaining support. It will outmatch REST once tools supporting GraphQL are widely available. With support from major organizations like Shopify and GitHub, it is on its way.

To learn more, look at the GraphQL documents.

This article originally appeared as a guest submission on ContentLab.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
Vigneshwaran Balasubramani is an experienced software engineer and an author at ContentLab. He is skilled in Angular, React, React Native, JavaScript, NodeJS, Docker, and following programming best practices.

Comments and Discussions

 
-- There are no messages in this forum --