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
Development Phase
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.
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.
touchindex.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
varexpress = require("express"),
app = express(),
port = 3070;
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!!.
nodeindex.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
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.
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
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”.
// changes - create separate folder routes andtwofiles 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.