Build a Simple GraphQL API Server With Express and NodeJS

Build a Simple GraphQL API Server With Express and NodeJS

Build a Simple GraphQL API Server With Express and NodeJS ... resolvers, resolver functions talks to a 3rd party API or our database and ends up returning ...👏👏👏👏👏

Build a Simple GraphQL API Server With Express and NodeJS ... resolvers, resolver functions talks to a 3rd party API or our database and ends up returning

GraphQL is a query language for APIs that offers declarative data fetching. It enables clients to ask for the exact data they need from a web server and nothing more. Developed in 2012 by Facebook, GraphQL API is currently being used in-house by Facebook and other companies such as Yelp, Shopify and Github. A GraphQL spec released in 2015 and is now available in many environments and used by teams of all sizes. GraphQL is open-source and maintained by Facebook.

While REST APIs typically send requests to multiple endpoints, GraphQL API allows you to send just a single request to an endpoint to retrive data needed for your application. GraphQL is great for slow mobile network connections because it needs just one round-trip to the server to get the data it needs. Using GraphQL, front-end engineers can construct a query based on the fields they need from the endpoint rather than overfetching resources from a REST API.

Versioning APIs can be headache for development teams. With GraphQL you have no worries. GraphQL allows you to add new fields and types (this will be discussed later on) to your GraphQL API without affecting existing queries. Older and unused fields can be deprecated and hidden from API clients. By using a single evolving version, GraphQL APIs give your application constant access to newer API implementations and allows clean and easily maintainable code base.

Table of Contents

  • Prerequisite
  • Setting up GraphQL and Express
  • Basic GraphQL API Implementation
  • Introduction
  • Types in GraphQL
  • Root Query
  • Defining a Schema
  • GraphQL API implementation using GraphQL schema language
  • Conclusion
Prerequisite

Before starting, make sure you have preferrably Node v6 installed. Open your command-line utitlity or terminal and type the command below:

node -v
# expected outcome or similar - v6.10.3

If you can't find Node installed, go the URL: https://nodejs.org/ and follow the instructions to install it.

Setting up GraphQL and Express

A simple way to create a GraphQL API server is to use Express, a popular web application framework for Node.js. To get Express up and running you'll need to install it using npm:

//follow the instructions to create a package.json file.
npm init 
npm install express --save

Then, install graphql and express-graphql dependencies like this:

Let's have a sneak peak into the power that GraphQL API wields. We are going to be using the buildSchema object from graphql to create a schema. Create a example.js file in the root directory and add this code:

// example.js
const express = require('express');
const { buildSchema } = require('graphql');
const graphqlHTTP = require('express-graphql');
let port = 3000;

/* Here a simple schema is constructed using the GraphQL schema language (buildSchema). 
   More information can be found in the GraphQL spec release */

let schema = buildSchema(`
  type Query {
    postTitle: String,
    blogTitle: String
  }
`);

// Root provides a resolver function for each API endpoint
let root = {
  postTitle: () => {
    return 'Build a Simple GraphQL Server With Express and NodeJS';
  },
  blogTitle: () => {
    return 'scotch.io';
  }
};

const app = express();
app.use('/', graphqlHTTP({
  schema: schema,
  rootValue: root,
  graphiql: true //Set to false if you don't want graphiql enabled
}));

app.listen(port);
console.log('GraphQL API server running at localhost:'+ port);

example.js contains a basic structure of graphql. This API is implemented using the GraphQL schema language. Express is not needed to execute this file. In your CLI terminal execute example.js using the node command:

node example.js

This is just to show you a quick example of a GraphQL API. I would explain later in this tutorial GraphQL Schema and how it works.

A key feature using graphiql is that it allows you to test your API in the browser, autocomplete and make suggestions for you based on the types and fields available in your defined schema.

npm install graphql express-graphql --save 

The --save flag is to add it as a dependency in your application so that anyone that installs your application automatical installs the dependencies when npm install is initiated.

The initial structure of the folder will look like this:

 |---- node_modules // this folder stores packages installed locally in a project 
 |---- package.json //stores information about your application

Basic GraphQL API Implementation

There you go! You have queried your GraphQL API.

Introduction

By now you should have an understanding of how GraphQL works. Let's get started with building an Express GraphQL server. In the root directory create a folder src, inside src folder create a file and save it as schema.js. Now open the file and add this code:

const Authors = require('./data/authors'); // This is to make available authors.json file
const Posts = require('./data/posts'); // This is to make available post.json file

/* Here a simple schema is constructed without using the GraphQL query language. 
  e.g. using 'new GraphQLObjectType' to create an object type 
*/

let {
  // These are the basic GraphQL types need in this tutorial
  GraphQLString,
  GraphQLList,
  GraphQLObjectType,
  // This is used to create required fileds and arguments
  GraphQLNonNull,
  // This is the class we need to create the schema
  GraphQLSchema,
} = require('graphql');

The code is self explanatory. If you don't understand it, I bet you would as you go on in this tutorial. Create a data folder inside src folder and copy the content of authors.json and posts.jsonfiles available at: https://github.com/codediger/graphql-express-nodejs/tree/master/src/data

Types in GraphQL

GraphQL has a graphql/type module used in type definition. Types can be imported from the graphql/type module or from the root graphql module

Basic Types include IDStringIntFloat and Boolean. We would be adding an AuthorType to our schema.js file:

const AuthorType = new GraphQLObjectType({
  name: "Author",
  description: "This represent an author",
  fields: () => ({
    id: {type: new GraphQLNonNull(GraphQLString)},
    name: {type: new GraphQLNonNull(GraphQLString)},
    twitterHandle: {type: GraphQLString}
  })
});

What this does is to create an object of a GraphQLObjectTypeName is self descriptive. Description is self descriptive. Fields contain the attributes of the Author Schema such as the author's idname and twitterHandle which all have their types defined. For more explanation on types check graphql.org/graphql-js/type/

Let's create our PostType:

const PostType = new GraphQLObjectType({
  name: "Post",
  description: "This represent a Post",
  fields: () => ({
    id: {type: new GraphQLNonNull(GraphQLString)},
    title: {type: new GraphQLNonNull(GraphQLString)},
    body: {type: GraphQLString},
    author: {
      type: AuthorType,
      resolve: function(post) {
        return _.find(Authors, a => a.id == post.author_id);
      }
    }
  })
});

Add it to schema.js This will create a PostType object to be used in the Root Query.

Root Query

Root query is an entry point to your GraphQL API server. It is used to expose the resources available to clients of your application. We would be making two resources available: authors and posts.

Let's add this to the schema.js file:

// This is the Root Query
const BlogQueryRootType = new GraphQLObjectType({
  name: 'BlogAppSchema',
  description: "Blog Application Schema Query Root",
  fields: () => ({
    authors: {
      type: new GraphQLList(AuthorType),
      description: "List of all Authors",
      resolve: function() {
        return Authors
      }
    },
    posts: {
      type: new GraphQLList(PostType),
      description: "List of all Posts",
      resolve: function() {
        return Posts
      }
    }
  })
});

Here Root query is defined as BlogQueryRootTypename and description is self descriptive. If you noticed, there is a new type declared: new GraphQLList(). What GraphQLList does is to create a type wrapper around other types that represents a list of those types.

Defining a Schema

Schema defines how you want the data in your application to be shaped and how you want the data to be related with each other. Schema defination affects the way data will be stored in your database(s). In schema defination you’ll also be defining what queriesmutations, and subscriptions that will be made available to the front-end displaying the data.

Lets add this schema to our file:

// This is the schema declaration
const BlogAppSchema = new GraphQLSchema({
  query: BlogQueryRootType
  // If you need to create or updata a datasource, 
  // you use mutations. Note:
  // mutations will not be explored in this post.
  // mutation: BlogMutationRootType 
});

Here query is assigned the BlogQueryRootType object to be used as the root query of the API.

GraphQL API implementation using GraphQL schema language

We will be needing a package lodash. Lodash is a toolkit of Javascript functions that provides clean, performant methods for manipulating objects and collections. If you're familiar with the underscore library that's great!. Lodash was created from it with some modifications made to provide additional functionality and deal with some performance issues in the underscore library.

npm install lodash --save

This will install the lodash package and save it as a dependency in your package.json file.

Add the following code at the top in your schema.js:

const _ = require('lodash');

The following line of code makes the lodash library functionalities usable in schema.js.

Now let's take a look into the schema.js file, this is how schema.js file should look. You can get it on github: https://github.com/codediger/graphql-express-nodejs/blob/master/src/schema.js

// schema.js
const _ = require('lodash');

// Authors and Posts get data from JSON Arrays in the respective files.
const Authors = require('./data/authors');
const Posts = require('./data/posts');


/* Here a simple schema is constructed without using the GraphQL query language. 
  e.g. using 'new GraphQLObjectType' to create an object type 
*/

let {
  // These are the basic GraphQL types need in this tutorial
  GraphQLString,
  GraphQLList,
  GraphQLObjectType,
  // This is used to create required fileds and arguments
  GraphQLNonNull,
  // This is the class we need to create the schema
  GraphQLSchema,
} = require('graphql');

const AuthorType = new GraphQLObjectType({
  name: "Author",
  description: "This represent an author",
  fields: () => ({
    id: {type: new GraphQLNonNull(GraphQLString)},
    name: {type: new GraphQLNonNull(GraphQLString)},
    twitterHandle: {type: GraphQLString}
  })
});

const PostType = new GraphQLObjectType({
  name: "Post",
  description: "This represent a Post",
  fields: () => ({
    id: {type: new GraphQLNonNull(GraphQLString)},
    title: {type: new GraphQLNonNull(GraphQLString)},
    body: {type: GraphQLString},
    author: {
      type: AuthorType,
      resolve: function(post) {
        return _.find(Authors, a => a.id == post.author_id);
      }
    }
  })
});

// This is the Root Query
const BlogQueryRootType = new GraphQLObjectType({
  name: 'BlogAppSchema',
  description: "Blog Application Schema Root",
  fields: () => ({
    authors: {
      type: new GraphQLList(AuthorType),
      description: "List of all Authors",
      resolve: function() {
        return Authors
      }
    },
    posts: {
      type: new GraphQLList(PostType),
      description: "List of all Posts",
      resolve: function() {
        return Posts
      }
    }
  })
});

// This is the schema declaration
const BlogAppSchema = new GraphQLSchema({
  query: BlogQueryRootType
  // If you need to create or updata a datasource, 
  // you use mutations. Note:
  // mutations will not be explored in this post.
  // mutation: BlogMutationRootType 
});

module.exports = BlogAppSchema;

If you notice in PostType, we have an additional attribute resolve. The function of resolve is perform operations that involve data manipulation or transformation with a value returned at the end of the operation.

Types and query has already been discussed above. BlogAppSchema will be exported to the server.js file using module.exports and by exporting BlogAppSchema we make everything available to our server.js file.

Create aserver.js file in the root directory and add this code:

// server.js

/*    
    Required modules {express and express-graphql} 
    will be imported along with the schema object
    from the schema.js file in src/schema.js 
*/

const express = require('express');
const graphqlHTTP = require('express-graphql');
const schema = require('./src/schema.js');

let port = 3000;
const app = express();
app.use('/', graphqlHTTP({
  schema: schema,
  graphiql: true //set to false if you don't want graphiql enabled
}));

app.listen(port);
console.log('GraphQL API server running at localhost:'+ port);

We can test is at localhost:3000. In the root directory, open CLI terminal and execute:

node server.js

Result:

This is how the server will come up. This is graphiql and its helps you query your API in the browser. To test the API type the following query:

{ posts{ id title author{ name } } } 

The result should look like this:

Conclusion

I am so excited and proud to have completed this tutorial with you. This is how to create a GraphQL API server powered by Express and NodeJS. I hope the tutorial was interesting and you learn't alot. Let me know if you have any questions or contributions. I would be glad to hear it!

=================================================================

Thanks for reading :heart: If you liked this post, share it with all of your programming buddies! Follow me on Facebook | Twitter

Learn More

☞ The Complete Node.js Developer Course (3rd Edition)

☞ Angular & NodeJS - The MEAN Stack Guide

☞ NodeJS - The Complete Guide (incl. MVC, REST APIs, GraphQL)

Top 7 Most Popular Node.js Frameworks You Should Know

Top 7 Most Popular Node.js Frameworks You Should Know

Node.js is an open-source, cross-platform, runtime environment that allows developers to run JavaScript outside of a browser. In this post, you'll see top 7 of the most popular Node frameworks at this point in time (ranked from high to low by GitHub stars).

Node.js is an open-source, cross-platform, runtime environment that allows developers to run JavaScript outside of a browser.

One of the main advantages of Node is that it enables developers to use JavaScript on both the front-end and the back-end of an application. This not only makes the source code of any app cleaner and more consistent, but it significantly speeds up app development too, as developers only need to use one language.

Node is fast, scalable, and easy to get started with. Its default package manager is npm, which means it also sports the largest ecosystem of open-source libraries. Node is used by companies such as NASA, Uber, Netflix, and Walmart.

But Node doesn't come alone. It comes with a plethora of frameworks. A Node framework can be pictured as the external scaffolding that you can build your app in. These frameworks are built on top of Node and extend the technology's functionality, mostly by making apps easier to prototype and develop, while also making them faster and more scalable.

Below are 7of the most popular Node frameworks at this point in time (ranked from high to low by GitHub stars).

Express

With over 43,000 GitHub stars, Express is the most popular Node framework. It brands itself as a fast, unopinionated, and minimalist framework. Express acts as middleware: it helps set up and configure routes to send and receive requests between the front-end and the database of an app.

Express provides lightweight, powerful tools for HTTP servers. It's a great framework for single-page apps, websites, hybrids, or public HTTP APIs. It supports over fourteen different template engines, so developers aren't forced into any specific ORM.

Meteor

Meteor is a full-stack JavaScript platform. It allows developers to build real-time web apps, i.e. apps where code changes are pushed to all browsers and devices in real-time. Additionally, servers send data over the wire, instead of HTML. The client renders the data.

The project has over 41,000 GitHub stars and is built to power large projects. Meteor is used by companies such as Mazda, Honeywell, Qualcomm, and IKEA. It has excellent documentation and a strong community behind it.

Koa

Koa is built by the same team that built Express. It uses ES6 methods that allow developers to work without callbacks. Developers also have more control over error-handling. Koa has no middleware within its core, which means that developers have more control over configuration, but which means that traditional Node middleware (e.g. req, res, next) won't work with Koa.

Koa already has over 26,000 GitHub stars. The Express developers built Koa because they wanted a lighter framework that was more expressive and more robust than Express. You can find out more about the differences between Koa and Express here.

Sails

Sails is a real-time, MVC framework for Node that's built on Express. It supports auto-generated REST APIs and comes with an easy WebSocket integration.

The project has over 20,000 stars on GitHub and is compatible with almost all databases (MySQL, MongoDB, PostgreSQL, Redis). It's also compatible with most front-end technologies (Angular, iOS, Android, React, and even Windows Phone).

Nest

Nest has over 15,000 GitHub stars. It uses progressive JavaScript and is built with TypeScript, which means it comes with strong typing. It combines elements of object-oriented programming, functional programming, and functional reactive programming.

Nest is packaged in such a way it serves as a complete development kit for writing enterprise-level apps. The framework uses Express, but is compatible with a wide range of other libraries.

LoopBack

LoopBack is a framework that allows developers to quickly create REST APIs. It has an easy-to-use CLI wizard and allows developers to create models either on their schema or dynamically. It also has a built-in API explorer.

LoopBack has over 12,000 GitHub stars and is used by companies such as GoDaddy, Symantec, and the Bank of America. It's compatible with many REST services and a wide variety of databases (MongoDB, Oracle, MySQL, PostgreSQL).

Hapi

Similar to Express, hapi serves data by intermediating between server-side and client-side. As such, it's can serve as a substitute for Express. Hapi allows developers to focus on writing reusable app logic in a modular and prescriptive fashion.

The project has over 11,000 GitHub stars. It has built-in support for input validation, caching, authentication, and more. Hapi was originally developed to handle all of Walmart's mobile traffic during Black Friday.

How to Create a Secure Node.js GraphQL API

How to Create a Secure Node.js GraphQL API

How to Create a Secure Node.js GraphQL API - This GraphQL tutorial outlines how to create an API for use in Node.js projects and examines how it compares to REST-based solutions...

In this article, we aim to present a quick guide on how to create a secure Node.js GraphQL API.

Some questions that may come to mind could be:

  • What is the purpose of using a GraphQL API?
  • What is a GraphQL API?
  • What is a GraphQL query?
  • What is the benefit of GraphQL?
  • Is GraphQL better than REST?
  • Why do we use Node.js?

All those are valid questions, but before answering them, we should dive into a brief overview of the current state of web development:

  • Almost every solution that you will find today uses some kind of application programming interface (API).
  • Even if you just use a social network, such as Facebook or Instagram, you are still connected to a front-end that consumes an API.
  • If you are curious, you will find that almost all online entertainment services use a different kind of API, including services like Netflix, Spotify, and YouTube.

How to Create a Secure Node.js GraphQL API - This GraphQL tutorial outlines how to create an API for use in Node.js projects and examines how it compares to REST-based solutions...

In virtually every scenario, you will find an API that you don’t need to know in detail, e.g., you don’t need to know how they were built, and you don’t need to use the same technology they used to be able to integrate it into your own system. The API that is provided allows you to offer a way to communicate between services in a common standard that both the service and the client can communicate without having to depend on a specific technology stack.

With a well-structured API, it is possible to have a solid, maintainable, and scalable API that can serve multiple kinds of clients and front-end applications.

That Said, What Is GraphQL API?

GraphQL is a query language for APIs, developed for internal use in Facebook and published for public use in 2015. It supports reading, writing, and real-time updates. It is also open source, and it is commonly compared to REST and other architectures. It is, in a nutshell, based on:

  • GraphQL Queries - This allows the client to read and manipulate how the data should be received.
  • GraphQL Mutations - This is how to write data on the server. It is the GraphQL convention on how to write data into the system.

Although this article is supposed to demonstrate a simple, yet real-world scenario on how to build and use GraphQL APIs, we will not provide a detailed introduction into GraphQL. The reason is simple, as the GraphQL team provides comprehensive documentation and lists several best practices in their Introduction to GraphQL.

What Is a GraphQL Query?

As described before, a query is the way that a client can read and manipulate data from the API. You can pass the type of an object and select which kind of fields you want to receive back. A simple query would be like the following:

query{
  users{
    firstName,
    lastName
  }
}

In this query, we are trying to reach all users from our users’ schema but only receiving firstNameand lastName. The result of this query would be like, for example:

{
  "data": {
    "users": [
      {
        "firstName": "Marcos",
        "lastName": "Silva"
      },
      {
        "firstName": "Paulo",
        "lastName": "Silva"
      }
    ]
  }
}

It is quite simple for client usage.

What Is the Purpose of Using a GraphQL API?

The purpose of creating an API is the ability to have software as a service that can be integrated by other external services. Even if your application is consumed by a single front-end, you can consider this front-end as an external service, and for that, you will be able to work in different projects when the communication between the two is provided via the API.

If you work in a large team, it can be split up to create a front-end and back-end team, allowing both to use the same technology and make their jobs easier. When architecting an API, it is important to choose the better fit for the project and what brings you closer to your desired solution.

In this article, we will be focusing on a skeleton for building an API that uses GraphQL.

Is GraphQL Better Than REST?

It may be a bit of a cop-out, but I can’t help it: That depends.

GraphQL is an approach that fits several scenarios very well. REST is an architecture approach that is proven in several scenarios as well. Nowadays, there are tons of articles that explain why one is better than the other or why you should use only REST instead of GraphQL. And also, a lot of ways that you can use GraphQL internally and still maintain the API’s endpoints as a REST-based architecture.

The best guidance would be to know the benefits of each approach, analyze the solution you are creating, evaluate how comfortable your team is working with the solution, and assess whether or not you will be able to guide your team to learn and get up to speed fast before choosing between approaches.

This article is more of a practical guide rather than a subjective comparison of GraphQL and REST. In case you’d like to read a detailed comparison of the two, I suggest you check out another one of our articles, GraphQL vs. REST - A GraphQL Tutorial.

In today’s article, we will focus on creating a GraphQL API using Node.js.

Why Do We Use Node.js?

GraphQL has several different libraries you can use. For the purpose of this article, we decided to go with the idea of using JavaScript with Node.js due to their widespread use and the fact that Node.js allows developers to use familiar front-end syntax for server-side development.

It is also useful to compare with our approach with a REST-based API, similar to the one that was demonstrated in another Toptal Engineering Blog article: Creating a Secure REST API in Node.js. This article also showcases the use of Node.js with Express to develop a skeleton REST API which will allow you to compare some differences between these two approaches. Node.js was also designed with scalable network applications, a global community, and several open-source libraries that you can find at the npm website.

This time around, we are going to show how to build a skeleton API with GraphQL, Node.js, and Express!

Hands on GraphQL Tutorial

As outlined earlier, we’ll be building a skeleton idea for GraphQL API, and you will need to know the basics of Node.js and Express before proceeding. The source code of the project made for this GraphQL example is available here.

We are going to handle two types of resources:

  • Users, for which we will handle a basic CRUD.
  • Products, for which we will have a bit of detail to show more of the power of GraphQL.

The users will contain the following structure:

  • id
  • firstname
  • lastname
  • email
  • password
  • permissionLevel

The products will contain the following structure:

  • id
  • name
  • description
  • price

As for the coding standard, we are going to use TypeScript for this project. In the source file, you will be able to configure everything to start coding with TypeScript.

Let’s Code!

First of all, make sure you have the latest Node.js version installed. At the time of publication, the current version is 10.15.3, as per Nodejs.org.

Initializing the Project

Let’s start in a new folder that we can name node-graphql. There, we can open a terminal or a Git CLI console and start the magic using the following command: npm init.

Configuring our Dependencies and TypeScript

To speed up the process, replacing your package.json with the following at our Git repository should contain all necessary dependencies:

{
  "name": "node-graphql",
  "version": "1.0.0",
  "description": "",
  "main": "dist/index.js",
  "scripts": {
    "tsc": "tsc",
    "start": "npm run tsc && node ./build/app.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@types/express": "^4.16.1",
    "@types/express-graphql": "^0.6.2",
    "@types/graphql": "^14.0.7",
    "express": "^4.16.4",
    "express-graphql": "^0.7.1",
    "graphql": "^14.1.1",
    "graphql-tools": "^4.0.4"
  },
  "devDependencies": {
    "tslint": "^5.14.0",
    "typescript": "^3.3.4000"
  }
}

With the updated package.json, just hit the terminal again and use: npm install. It will install all dependencies needed to run this GraphQL API within Node.js and Express.

The next piece is to configure our TypeScript mode. We need a file called tsconfig.json in our root folder with the following:

{
  "compilerOptions": {
    "target": "ES2016",
    "module": "commonjs",
    "outDir": "./build",
    "strict": true,
    "esModuleInterop": true
  }
}

The logic of the code for this configuration will be present at the app folder. There we can create an app.ts file and for basic testing add the following code there:

console.log('Hello Graphql Node API tutorial');

By our configuration, we now can run npm start and wait for a build and be able to test that everything is working properly. In your terminal console, you should see our “Hello GraphQL Node API tutorial.” In the back scene, the configuration basically compiles the TypeScript code into pure JavaScript and then executes our build in the build folder.

Now let’s configure a basic skeleton for our GraphQL API. For starting our project, we are going to add three basic imports:

  • Express
  • Express-graphql
  • Graphql-tools

Let’s start putting it all together:

import express from 'express';
import graphqlHTTP from 'express-graphql';
import {makeExecutableSchema} from 'graphql-tools';

Now we should be able to start to code a bit. The next step is to deal with our app in Express and the basic GraphQL configuration like:

import express from 'express';
import graphqlHTTP from 'express-graphql';
import {makeExecutableSchema} from 'graphql-tools';

const app: express.Application = express();
const port = 3000;


let typeDefs: any = [`
  type Query {
    hello: String
  }
     
  type Mutation {
    hello(message: String) : String
  }
`];

let helloMessage: String = 'World!';

let resolvers = {
    Query: {
        hello: () => helloMessage
    },
    Mutation: {
        hello: (_: any, helloData: any) => {
            helloMessage = helloData.message;
            return helloMessage;
        }
    }
};


app.use(
    '/graphql',
    graphqlHTTP({
        schema: makeExecutableSchema({typeDefs, resolvers}),
        graphiql: true
    })
);
app.listen(port, () => console.log(`Node Graphql API listening on port ${port}!`));

What we are doing is:

  • Enabling port 3000 for our Express server app.
  • Defining which queries and mutations we want to use as a quick example.
  • Defining how the queries and mutations are going to work.

OK, but what is going on for typeDefs and resolvers, as well as relation to queries and mutations?

  • typeDefs - The definition of our schema of what we can expect from queries and mutations.
  • Resolvers - Instead of the expectation of fields or required parameters, here we define the functions and behaviors of how should the queries and mutations would work.
  • Queries - The “gets” that we want to read from the server.
  • Mutations - Our requests that are going to affect any data that we have on our own server.

Now, let’s run npm start again to see what we have there. We would expect that the app will run with the following message: Node Graphql API listening on port 3000!

We can now try to query and test the GraphQL API on our own server via: http://localhost:3000/graphql

Great, now we can write our first very own query which was defined as “hello.”

Note that the way we defined it at the typeDefs, the page can help us to build the query.

That’s great, but how can we change the value? Mutations!

Now, let’s see what happens when we change our in-memory value with a mutation:

Now we can do basic CRUD operations with our GraphQL Node.js API. Let’s advance with our code now.

Products

For products, we will use a module called products. As an effort to simplify this article, we are going to use an in-memory database just for demonstration. We will define a model and a service to manage products.

Our model will be based as follows:

export class Product {
  private id: Number = 0;
  private name: String = '';
  private description: String = '';
  private price: Number = 0;

  constructor(productId: Number,
    productName: String,
    productDescription: String,
    price: Number) {
    this.id = productId;
    this.name = productName;
    this.description = productDescription;
    this.price = price;
  }

}

The service which will communicate with GraphQL will be defined as:

export class ProductsService {

    public products: any = [];

    configTypeDefs() {
        let typeDefs = `
          type Product {
            name: String,
            description: String,
            id: Int,
            price: Int
          } `;
        typeDefs += ` 
          extend type Query {
          products: [Product]
        }
        `;

        typeDefs += `
          extend type Mutation {
            product(name:String, id:Int, description: String, price: Int): Product!
          }`;
        return typeDefs;
    }

    configResolvers(resolvers: any) {
        resolvers.Query.products = () => {
            return this.products;
        };
        resolvers.Mutation.product = (_: any, product: any) => {
            this.products.push(product);
            return product;
        };

    }

}

Users

For users, we will follow the same structure as the products module. We will have a model and a service for users. The model will be defined as:

export class User {
    private id: Number = 0;
    private firstName: String = '';
    private lastName: String = '';
    private email: String = '';
    private password: String = '';
    private permissionLevel: Number = 1;

    constructor(id: Number,
                firstName: String,
                lastName: String,
                email: String,
                password: String,
                permissionLevel: Number) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
        this.password = password;
        this.permissionLevel = permissionLevel;
    }

}

Meanwhile, our service will be like:

const crypto = require('crypto');

export class UsersService {

    public users: any = [];

    configTypeDefs() {
        let typeDefs = `
          type User {
            firstName: String,
            lastName: String,
            id: Int,
            password: String,
            permissionLevel: Int,
            email: String
          } `;
        typeDefs += ` 
          extend type Query {
          users: [User]
        }
        `;

        typeDefs += `
          extend type Mutation {
            user(firstName:String,
             lastName: String,
             password: String,
             permissionLevel: Int,
             email: String,
             id:Int): User!
          }`;
        return typeDefs;
    }

    configResolvers(resolvers: any) {
        resolvers.Query.users = () => {
            return this.users;
        };
        resolvers.Mutation.user = (_: any, user: any) => {
            let salt = crypto.randomBytes(16).toString('base64');
            let hash = crypto.createHmac('sha512', salt).update(user.password).digest("base64");
            user.password = hash;
            this.users.push(user);
            return user;
        };

    }

}

As a reminder, the source code is available for use from this link.

Now we can play and test our code. Let’s run npm start. We will have the server running at port 3000. We can now access GraphQL for testing at http://localhost:3000/graphql.

Let’s try a mutation to add an item to our product list:

To test if it worked, we will now use a query for products, but receiving only id, name, and price

query{
  products{
    id,
    name,
    price
  }
}

The response will be:
{
  "data": {
    "products": [
          {
        "id": 100,
        "name": "My amazing product",
        "price": 400
      }
    ]
  }
}

And that’s it; the product is working as expected. Now we can play and switch the fields around if we want to. You can try to add a description:

query{
  products{
    id,
    name,
    description,
    price
  }
}

Now we can have the descriptions of our products. Let’s try users now.

mutation{
  user(id:200,
  firstName:"Marcos",
  lastName:"Silva",
  password:"amaz1ingP4ss",
  permissionLevel:9,
  email:"[email protected]") {
    id
  }
}

And a query will be like:

query{
  users{
    id,
    firstName,
    lastName,
    password,
    email
  }
}

With a response like:

{
  "data": {
    "users": [
      {
        "id": 200,
        "firstName": "Marcos",
        "lastName": "Silva",
        "password": "kpj6Mq0tGChGbZ+BT9Nw6RMCLReZEPPyBCaUS3X23lZwCCp1Ogb94/oqJlya0xOBdgEbUwqRSuZRjZGhCzLdeQ==",
        "email": "[email protected]"
      }
    ]
  }
}

And now our GraphQL skeleton is ready! There are tons of steps from here towards a useful, fully functional API, but the basic core is now set.

Summary and Final Thoughts

Even cutting edges to shorten up, the article is quite big with a lot of basic information regarding the development of a GraphQL Node.js API.

Let’s review what we’ve covered so far:

  • Usage of Node.js with Express and GraphQL to build a GraphQL API;
  • Basic GraphQL use;
  • Basic usage of queries and mutations;
  • Basic approach to creating modules for your project;
  • Testing our GraphQL API;

To focus more on the development side of things, we avoided several important items which can briefly be summarized as follows:

  • Validations for new items;
  • Handling errors properly with a generic error service;
  • Validating fields that a user can use at each request with a generic service;
  • Add a JWT interceptor to secure the API;
  • Handle password hash with a more effective approach;
  • Add unit and integration tests;

Remember that we have the full source code at this Git link. Feel free to use, fork, open issues, make pull requests, and play with it! Please note that all standards and suggestions made in this article are not carved in stone.

This is just one of many approaches that can be used to start designing your own GraphQL API. Also, be sure to read and explore GraphQL in more detail, learning what it has to offer and how it can make your APIs even better.