Building Real-World Microservices with Node.js

Building Real-World Microservices with Node.js

This article is intended to be a quick-start guide for developing real-world Microservices with Node.js.

Originally published by Mike Mackrory at https://blog.cloud66.com

It’s the article that I would have liked to read when I started programming with Node.js. Therefore, you won’t find the words “Hello” or “World” anywhere in this article (at least, not more than that first mention). You should have a basic understanding of Javascript, but other than that, follow the steps for a working application.

In our highly connected world, projects can be constructed by combining functionality from different APIs in unique and performant ways. In this example, we’re going to create a Microservice using Node.js which connects to an external API, and then look at improvements we can make to make it more cost-effective and performant.

The business requirement for this service is to accept two Zip Codes and return the distance between them in miles. We’ll look at validation techniques, the configuration for an external API call, and implement an internal cache to make duplicate calls faster and more cost-efficient.

Initial Steps

You’ll need to have Node.js installed on your workstation for this example. I’m using version 8.11, and you can download the latest version for your operating system from Nodejs.org. The Node.js installation includes NPM, which is the Node.js package manager. We’ll use NPM to bootstrap the project, install dependencies and execute the service. (You can follow along with this example or view the completed example in this GitHub repository.)

We’ll start by initializing the project using npm init. Run this command in the root folder for the project. The command walks you through the creation of the package.json file, which is the foundation for the project. If you’re not sure of an answer, accept the default, and we can update it later if necessary. We’ll be using the name and version a little later.

$ npm init 

We’re going to use a package called Express to build our service. Express is an established framework for Node applications and continues to benefit from the support of the Node.js Foundation. We’re also going to use the Request package to enable us to connect with a third-party API on the Web.

We’ll add these packages to our project with the following command (the save flag at the end of the command adds it to the package.json file which was created by NPM).

$ npm install express request --save 

One last thing before we delve into the code. Let’s look at the structure of how it’s all going to fit together. There are two files and a folder created by the npm init command. These are package.json, package-lock.json, and node_modules. When we installed the express and request packages, their dependencies were downloaded and saved in node_modules.


The primary file in our project is named server.js. We’ll have files to support the API in a folder called api, and we’ll add the logic to connect to a third-party API in the service folder.

Let’s build our service!

Creating a Server to Accept Requests

We’ll start from our primary file, then define the routes, add controllers, and finally, build the connection to an external service.

Create a file in the root folder for your project called server.js. This file contains the code below. I’ll step through each part of it, so you can see how it goes together.

var express = require('express')
var app = express();
var port = process.env.PORT || 3000;

var routes = require('./api/routes'); routes(app); app.listen(port, function() {   console.log('Server started on port: ' + port); });

This file creates our server and assigns routes to process all requests. We’re going to have two endpoints which we’ll define in the next step.

The first thing we’ll do is to bring the express package into the file. We’ll use this to create a new app object. We’ll also specify the port. The process object is used to reference system properties. If I want to define the port number based on the machine running the application, I can define an environment variable called PORT, and it will be used. The default port value is 3000 if it isn’t defined.

The next line brings in a routes object from the routes.js file in the api folder. We’ll pass the app to this object, and that sets the routes for our application. Finally, we’ll tell the app to start listening on the port we defined, and to display a message to the console when this process is complete.

Defining the Routes

The next step is to define the routes for the server and assign each to a target in our controller object. We’ll build the controller in the next step. We’ll have two endpoints. An about endpoint returns information about the application. A distance endpoint includes two path parameters, both Zip Codes. This endpoint returns the distance, in miles, between these two Zip Codes.

'use strict';

var controller = require('./controller');

module.exports = function(app) {   app.route('/about')       .get(controller.about);   app.route('/distance/:zipcode1/:zipcode2')       .get(controller.get_distance); };

The ‘use strict’ directive at the top of the file is used by new versions of Javascript to enforce secure coding practices. The first thing we’ll do is to create a controller object which we’ll define in the next step. Because we declare this outside of any functions in the file, it is accessible by all of them.

Module.exports allows us to declare functions inside a module, and have them available for use in another file. This file constitutes the routes module, which we imported into our primary server.js file and used it to define the routes for our express app.

This function adds two routes to the app. The first route listens for GET requests on the /about endpoint. These requests are handled by the about function in the controller. The second route listens for GET requests on the /distance endpoint. The get_distance function in the controller handles these requests. Two parameters are also specified. These are labeled zipcode1 and zipcode2 respectively.

Let’s build the controller to handle those requests.

Adding Controller Logic

One of the aspects of Javascript and Node.js which I find interesting is that functions are objects. Within the controller file, we’re going to create a controller object with two properties. Those properties are the functions to handle the requests we defined in the routes module.

'use strict';

var properties = require('../package.json') var distance = require('../service/distance');

var controllers = {   about: function(req, res) {       var aboutInfo = {           name: properties.name,           version: properties.version       }       res.json(aboutInfo);   },   get_distance: function(req, res) {           distance.find(req, res, function(err, dist) {               if (err)                   res.send(err);               res.json(dist);           });       }, };

module.exports = controllers;

We have two distinct parts to our controller. We’ll go through the code for the about functionality first. At the top, we create an object called properties which references the package.json file which NPM created when it bootstrapped the project. This file is in JavaScript Object Notation or JSON for short. This format affords us the ability to import and use the information it contains.

Within the controllers object, we define a property called about. This property is a function which accepts request and response objects. We’ll only use the response object for this function. Using the name and version information from the package.json file, we’ll build a new object and return it as the response.

For the get_distance functionality, we’ll start by bringing in the distance module. We’ll pass the request and response objects to the find function within this module. This function also includes a callback function. This function accepts an error object (err) and a distance object (dist). If there is an error in the response, we return that with our response; otherwise, we send back the results of the find function.

Making the External Call

We’re ready for the final piece of the puzzle. This file handles the call to a third-party API. We’ll use the distance API provided by ZipCodeAPI.com. (You need an API key to use this, and it is free if you register. You can also use the key from the example if you want to test your service, but this key frequently expires during the day.)

I set my key as an environment variable on my system and named it ZIPCODE_API_KEY. The default key in the code is an expired test key from the ZipCodeAPI website.

var request = require('request');

const apiKey = process.env.ZIPCODE_API_KEY || "hkCt1nW1wF1rppaEmoor7T9G4ta7R5wFSu8l1dokNz8y53gGZHDneWWVosbEYirC"; const zipCodeURL = 'https://www.zipcodeapi.com/rest/';

var distance = {   find: function(req, res, next) {       request(zipCodeURL + apiKey                + '/distance.json/' + req.params.zipcode1 + '/'                + req.params.zipcode2 + '/mile',       function (error, response, body) {           if (!error && response.statusCode == 200) {               response = JSON.parse(body);               res.send(response);           } else {               console.log(response.statusCode + response.body);               res.send({distance: -1});           }       });

  } };

module.exports = distance;

We’re using the request package to execute the external HTTP request, and we already discussed the api Key above. Ensure that you update it unless you want to start by testing the error conditions.

The find function accepts request, response and next objects as parameters. The request object accepts the URL of the service we’re calling and then defines a callback function to handle the response.

If there are no errors, and the status of the response is HTTP Status code 200, then the function parses out the body of the response into an object called response and returns it on the resp object. Since the ZipCodeAPI returns with a JSON response, we could forward this directly. Parsing it out allows us the option of doing more with the response if we choose to.

We log failures to the console, and then a result of -1 is sent on the response object. You may opt to create an error object to return as well.

Finally, we export the distance object, which allows the controller to instantiate it and call its functions as needed.

Execution and Debugging

Assuming there aren’t any typos, your application should be ready to execute. Open a console window and run the following commands—The first ensures that all the packages used by the application are downloaded and up-to-date:

$ npm install

The second command starts your application.

$ npm start

Assuming it starts correctly, and the port you define is 3000, you can now open your browser and navigate to:

http://localhost:3000/about

http://localhost:3000/distance/84010/97229

The following URL allows you to see the error condition because 92001 is not a recognized Zip Code.

http://localhost:3000/distance/84010/92001

If you run into problems, I’ve found the error messages to generally be helpful in pointing me to the line of code with the offending syntax, missing punctuation, or other problems. The Internet is also a wealth of information for specific problems.

Thanks for reading

If you liked this post, share it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading

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

Angular & NodeJS - The MEAN Stack Guide

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

Best 50 Nodejs interview questions from Beginners to Advanced in 2019

Node.js 12: The future of server-side JavaScript

An Introduction to Node.js Design Patterns

Basic Server Side Rendering with Vue.js and Express

An Introduction to Microservices

What is Microservices?

Build Spring Microservices and Dockerize Them for Production

Best Java Microservices Interview Questions In 2019

Build a microservices architecture with Spring Boot and Spring Cloud


node-js microservices javascript web-development web-service

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Hire Node.JS Developers | Skenix Infotech

We are providing robust Node.JS Development Services with expert Node.js Developers. Get affordable Node.JS Web Development services from Skenix Infotech.

Top Node.js Development Companies and Expert NodeJS Developers

A thoroughly researched list of top NodeJS development companies with ratings & reviews to help hire the best Node.JS developers who provide development services and solutions across the world. List of Leading Node.js development Service Providers...

How to Hire Node.js Developers And How Much Does It Cost?

A Guide to Hire Node.js Developers who can help you create fast and efficient web applications. Also, know how much does it cost to hire Node.js Developers.

Web Development Services

As one of the best Web Application Development Company, it provides a fine quality mobile app development service at an affordable price. Especially, it encourage start-ups that have unique ideas, by offering a more competitive price

Top Vue.js Developers in USA

Vue.js is an extensively popular JavaScript framework with which you can create powerful as well as interactive interfaces. Vue.js is the best framework when it comes to building a single web and mobile apps.