avatarBhargav Bachina

Summary

This article provides a step-by-step guide on creating a production-ready Node.js REST API using plain vanilla JavaScript, covering both development and production phases.

Abstract

The article begins by listing the required tools for the project, including Node.js, Visual Studio Code, nodemon, express, eslint, and webpack. It then outlines the development phase, which involves initial setup, logging, handling undefined routes, defining context paths, error handling, linting, and testing the project. The production phase covers webpack setup, environment variables, and Dockerizing the app. The author provides code snippets and explanations for each step, making it easy for developers to follow along and create their own production-ready Node.js REST APIs.

Bullet points

  • Tools required for the project: Node.js, Visual Studio Code, nodemon, express, eslint, and webpack
  • Development phase:
    • Initial setup: create a folder, initialize package.json, and install express
    • Logging: create a separate file for logging and import it in another file
    • Handling undefined routes: handle undefined or all other routes
    • Defining context paths: define a context path for the project and sub-context paths for modules
    • Error handling: not covered in the article
    • Linting: add eslint to the project to maintain coding standards
    • Testing: not covered in the article
  • Production phase:
    • Webpack setup: bundle the entire app files into a single file
    • Environment variables: read environment variables in Node.js REST API
    • Dockerize the app: containerize the app and run it in a container

How to write production-ready Node.js Rest API — Javascript version

A step by step guide with an example

Node.js Rest API

This article list out all the necessary ingredients for the production-ready Node.js rest API with plain vanilla javascript. I want to categorize this into two phases

  1. Development Phase
  2. Production Phase

Let’s not complicate things and create simple user API where you get a list of users with Get request and save a user with the post request. Since we are focussing on the Node.js rest API, let's go with the simple API. let’s download all the tools required for the project.

Tools Required:

For complete project

git clone https://github.com/bbachi/prod-ready-node-rest-api.git

follow the below article for step by step process

Development Phase

  • Initial setup
  • nodemon
  • Logging
  • How to handle undefined routes
  • How to define context path
  • Error Handling
  • Linting your project
  • Testing your project

Initial setup

Any node.js project starts with package.json let's create a folder called user_api and cd into it and do npm init. it will ask you all the details like the package name, version, author, etc. You can leave them blank or give some values that will create a package.json in your folder.

mkdir user_api
cd user_api
npm init

if you notice the package.json, index.js is the main file which is the starting file for the project. let's create index.js file at the root level and install the express.js framework. Express is a web application framework for node.js which we can use for creating HTTP server and configure routes for our project.

touch index.js
npm install express --save

whenever you install package and it will be added to the dependencies section as you can see below. you don’t have to add it manually when you do it with “ — save” flag, npm will take care of adding that into dependencies section.

let’s import express into index.js and create a Http server which listens on port 3070 and create a default route with “/”.

index.js

var express = require("express"),
    app = express(),
    port = 3070;
app.get("/", function(req, res) {
    res.send("App works!!");
})
app.listen(port, function(err) {
     console.log("running server on from port:::::::" + port);
});

run the below command and open the browser and hit http://localhost:3070and default route works!!.

node index.js
Default route working

Let's add scripts to package.json. scripts are a great place to add all your commands so that you can run with npm command. Add the below line to the scripts section in package.json. you can run with the command npm start

"scripts": {   
    "start": "node index.js",
    "test": "echo \"Error: no test specified\" && exit 1" 
 },

Let's add a couple of routes and test it in the browser. add the body-parser dependency express will use this middleware to access request data from the post request. Look at the complete index.js file and package.json file.

npm install body-parser --save
//in the index.js file
app.use(bodyParser.json());

nodemon

At this moment, we have full rest API with 4 routes including default. one problem that we have right now is a manual restart of the server whenever we edit any file. let's add nodemon. it’s a tool that automatically detects file changes in your directory and restarts the server without any manual intervention.

This is a dev dependency means only necessary for development, so the flag — save-dev. add another line to the scripts section so that we can run with npm.

npm install nodemon --save-dev
// dev dependencies will be added
"devDependencies": {
   "nodemon": "^1.18.10"
}
// scripts section in package.json
"scripts": {
   "start": "node index.js",
   "start:dev": "nodemon index.js",
   "test": "echo \"Error: no test specified\" && exit 1"
}

run the below npm command and edit the file you can see changes instantly without restart of the server. it boosts your productivity.

npm run start:dev
nodemon

Logging

Let’s set up logging for our project. create a new folder called logger with a file called logger.js. we can use any package like Winston, log4js, but we are not using those for simplicity purposes. This is how you create a separate file and import it in another file in nodejs.

Now you can see the logging is done by the logger that we created once you replace all console.log statements. in this way, you can control all your app logging from one file. you can add any third party package into that file without changes across the app.

logger.info("running server on from port:::::::" + port);

How to handle Undefined Routes

we defined default and three other routes in our service. let's handle undefined routes as well. what if the user tries to enter the wrong one or misspell the route. Make sure you add this route as the last route. if you add this at the beginning all the routes will be redirected to this.

// request to handle undefined or all other routes
app.get("*", function(req, res) {
   logger.info("users route");
   res.send("App works!!!!!");
})

How to define Context Path

we don’t have any context path for our project, Let’s define it. Since it is an API, let's define “/api” for all the routes and also define sub-context path for the user module which is “/user”.

after the below changes to all the files, path changes from http://localhost:3070/users to http://localhost:3070/api/user/users

// changes - create separate folder routes and two files under it
mkdir routes
cd routes
touch routes.js user.js

Error Handling

coming soon!!

Linting your project

Let’s add eslint to our project. it’s very important to have linting for your project to maintain the same coding standards across your team. run following commands in a sequence

// installs eslint global so that you can use eslint
npm install -g eslint
//installs eslint for the project
npm install eslint -save-dev
//it will create .eslintrc.js, while creating it will create bunch //of questions like which standards you want to use etc..
eslint --init
//add these below to scripts section in package.json
"eslint": "eslint ./",
"eslint-fix": "eslint ./ --fix",
eslint — lint

when you first run the below command you will have lot of eslint errors you can easily fix all these with the second command

npm run eslint
npm run eslint-fix
eslint errors

with the second command you can fix all the errors, if not fix it manually until you fix all the errors. warnings are fine.

errors with eslint

we have added two files for linting and package.json looks like it

Testing your project

coming soon

Production Phase

  • Webpack setup
  • Environment variables
  • Dockerize the app

Webpack setup

once development is complete, we need to bundle our app and deploy it into other environments like stage,uat, and prod, etc. Let’s add a webpack to our project to bundle the entire app files into a single file.

install the following to setup webpack

// install webpack global
npm install -g webpack
//install webpack and webpack-cli in the project
npm install webpack webpack-cli --save-dev
// add below to scripts section in package.json
"build": "webpack"

add the webpack.config.js where you mention starting file and output directory and the target is important because our runtime environment is the node.

when you run the below command webpack will build the entire project into single bundle file and place that in the target folder mentioned in the webpack.config.js

npm run build
webpack build

after the build complete, let's add the below npm script to the scripts section in the package.json and run the command

"prod": "node dist/api.bundle.js",
npm run prod //run this in the terminal

Environment variables

Here is a separate article on how to read environment variables in NodeJS REST API. In this, I explained 5 ways of reading environment variables. You can choose any of the methods depending on your project setup.

Reading Environment Variables in NodeJS REST API

Dockerize the app

Let’s containerize this app. Below is the article about how to build the image and run the app in the container. have a look:)

If you want to look at the typescript version of it. Here is the link.

JavaScript
Nodejs
Node For Begginners
Web Development
Software Development
Recommended from ReadMedium