Set up graphQL backend using Node.js, express and mongoDB - Step by Step

Hello everyone in this article we are going to learn how to setup graphQL backend server using Node.



# What is graphQL

* GraphQL is an open-source data query and manipulation language for APIs, and a runtime for fulfilling queries with existing data ( As per Wikipedia ).
* Developed by Facebook

If you want to know why for a specific problem we should use graphQL read this article

When should you consider GraphQL for your application?

First create a folder which will hold our node files say "graphql-node", within that folder do "npm init" to setup initial basic package.json file

Install below dependencies :

// for starting local server : Express
// for graphQL : graphql
// middleware : express-graphql


My package.json looks like below code

{
  "name": "graphql-node",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "app": "nodemon app"
  },
  "author": "",
  "license": "MIT",
  "dependencies": {
    "express": "^4.17.1",
    "express-graphql": "^0.9.0",
    "graphql": "^14.5.8"
  }
}

Notice within scripts I have added "app" with nodemon dependency which will help me restart my dev server whenever a file is changed which will save lots of time in future, if you don't have nodemon installed use npm i nodemon -g and which will install it globally

Now sets setup app.js file which will be our root file, in this file express server will be initiated and started

const express = require('express')
const graphqlMiddleWare = require('express-graphql')

const app = express()
app.use('/graphql',graphqlMiddleWare({
    
}))
app.listen(3001,()=>{
    console.log("running graphql server on 3001")
})

notice any route with '/graphql' will be handled by middleware 'express-graphql' , lets test run this file


Great it's running, now it we go to route "http://localhost:3001/graphql", it opens a page but it shows some message...


Hmm..so graphql is expecting a schema. That schema is going to explain about our data and how our graph will look to express-graphql. Which makes complete sense.

Let's take the same example of this article When should you consider GraphQL for your application?


From this example we can see we need to create two different GraphQL objecttypes one for Game and another for Publisher

Under root create a folder called model, and under that we need to create schema.js which will hold new objecttypes and relations

First take a list of games as dummy data

const games = [
    {name: "FIFA",id:"1",genre:"Sports, simulation"},
    {name: "PUBG",id:"2",genre:"Battle royale"},
    {name: "Call of Duty: Mobile",id:"3",genre:"First-person shooter, battle royale"}
]



Within 'graphql' package there is a GraphQLObjectType using which we can create different object types and mention fields with it's datatype

Let's create the GameType

const graphql = require('graphql')
const _ = require('lodash')
const { GraphQLObjectType,GraphQLString } = graphql 
const GameType = new GraphQLObjectType({
    name: 'Game',
    fields : () => ({
        name: {type : GraphQLString},
        id: {type : GraphQLString},
        genre: {type : GraphQLString}
    })
})

After creating the type we are going to need a RootQuery via which external apps(react app) will hook into the graph to fetch the data, within RootQuery whatever name we give to each key will be same as we write graph query in ui apps, we can also define args like game id which use can pass to query data. We will install and import lodash for quick array operations.


const RootQuery = new GraphQLObjectType({
    name: 'RootQueryType',
    fields:{
        game:{
            type: GameType,
            args: { id : { type: GraphQLString }},
            resolve(parents,args){
                return _.find(games,{ id : args.id })
            }
        }
    }
})

Within this resolve function we are going to fetch data from db and will hold relation between different types

Now we can export the schema and use it, but we need to import GraphQLSchema for that.

module.exports = new GraphQLSchema({
    query:RootQuery
})

As the setup is complete for schema so how are we expecting to query a particular game :

{
    game( id: "2" ):{
       name,
       genre
    }
}

But before using that we need to import schema in App file

const express = require('express')
const graphqlMiddleWare = require('express-graphql')
const schema = require('./model/schema')
const app = express()
app.use('/graphql',graphqlMiddleWare({
    schema
}))

Now start the app , using npm run app , install postman an test graphql endpoint


Great finally the data is being fetched using GraphQL and express.

Now lets setup the same configuration for Publishers entity also. So again we need some dummy data for publishers as well.

const publishers = [
    {name: "EA Sports",id:"1",established:"1991"},
    {name: "PUBG Corporation (Bluehole)",id:"2",established:"2007"},
    {name: "Activision",id:"3",established:"1979"},
]

In the same way we need to add an object type for publisher and modify root query object by adding the publisher field so that we can query for the same data

const PublisherType = new GraphQLObjectType({
    name: 'Publisher',
    fields : () => ({
        name: {type : GraphQLString},
        id: {type : GraphQLString},
        established: {type : GraphQLString}
    })
})

Updated rootquery :

const RootQuery = new GraphQLObjectType({
    name: 'RootQueryType',
    fields:{
        game:{
            type: GameType,
            args: { id : { type: GraphQLString }},
            resolve(parents,args){
                return _.find(games,{id : args.id})
            }
        },
        publishers:{
            type: PublisherType,
            args: { id : { type: GraphQLString }},
            resolve(parents,args){
                console.log(args)
                return _.find(publishers,{id : args.id})
            }
        }
    }
})

Now we can test publisher data via postman:



Great.. basics are set up.

Now next we will replace dummy data with original mongo DB operations but before that we need to add relations between two object type. Kindly follow the next article.

Thanks for your time and please subscribe my bog 

Comments

Popular posts from this blog

Best coding practice and structure for redux saga with react hooks | Separate watcher and worker saga | React clean code

How to use redux with React Hooks - Creating TodoList

Setting up Redux Devtools for React applications