Skip to main content

Let's build a GraphQL starter server with Node.js and Express

Greetings!

This is the second article of the GraphQL series, I would like to discuss the steps needed to create a GraphQL server using Node.js. Have a look at the first article if haven't read it yet.

The complete code can be found here

What we build

As the idea is to create a basic GraphQL server, we will expose the "Hello World" query.

Initializing the project

npm init -y
npm install express graphql express-graphql --save
npm install @babel/core @babel/node @babel/preset-env --save-dev
npm install nodemon --save-dev
Enable ES6 modules in package.json and add a start command for nodemon.
{
  "name": "nodejs-graphql-starter",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "start": "nodemon --exec babel-node index",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.18.1",
    "express-graphql": "^0.12.0",
    "graphql": "^16.6.0"
  },
  "devDependencies": {
    "@babel/core": "^7.19.3",
    "@babel/node": "^7.19.1",
    "@babel/preset-env": "^7.19.3",
    "nodemon": "^2.0.20"
  }
}
Create .bablerc and add below to setup babel
touch .babelrc
{
  "presets": ["@babel/preset-env"]
}
Our project structure is like below;


Configure Express server

Create index.js inside the root directory of the project. We are initiating an express server inside that and separating out the GraphQL setup into a separate module (graphql-schema.js).
import express from "express";
import configureGraphql from "./graphql-schema.js";

const app = express();

configureGraphql(app);

app.listen(3000, () => console.log('Running a GraphQL API server at http://localhost:3000/graphql'));

Configure GraphQL Schema

Create the file graphql-schema.js inside the root directory. We will add GraphQL related code in this module. First of all, we need to import graphql from graphql module and graphqlHTTP from express-graphql.
import { graphqlHTTP } from "express-graphql";
import graphql from 'graphql';
Instead of defining the schema using GraphQL schema language, we are constructing the schema programmatically. We can do that using GraphQLSchema constructor. In this approach, we create our Query using GraphQLObjectType. In this programmatic approach, we add a resolver in our Query type.

Our Query contains one field named message that resolves the string "Hello World!".
const RootQueryType = new graphql.GraphQLObjectType({
  name: 'RootQueryType',
  fields: {
    message: { 
      type: graphql.GraphQLString,
      resolve: () => "Hello world!"
    }
  }
});
The next step is to create the schema object using GraphQLSchema where we provide our root query.
const schema = new graphql.GraphQLSchema({ query: RootQueryType });
Finally, we configure the endpoint that exposes GraphQL schema.
function configureGraphql(app) {
  app.use('/graphql', graphqlHTTP({
    schema: schema,
    graphiql: true,
  }));
}
Note that we have exposed GraphQL UI by providing "graphiql: true".

We export the function so that we can pass the express app that we created in index.js.
import { graphqlHTTP } from "express-graphql";
import graphql from "graphql";

const RootQueryType = new graphql.GraphQLObjectType({
  name: 'RootQueryType',
  fields: {
    message: { 
      type: graphql.GraphQLString,
      resolve: () => "Hello world!"
    }
  }
});

const schema = new graphql.GraphQLSchema({ query: RootQueryType });

function configureGraphql(app) {
  app.use('/graphql', graphqlHTTP({
    schema: schema,
    graphiql: true,
  }));
}

export default configureGraphql;

Demo

npm start
We can access our application in the browser at http://localhost:3000/graphiql.


That's it! Happy learning ☺

References

https://graphql.org/graphql-js/
https://graphql.org/graphql-js/constructing-types/

Comments