Frank Joseph I'm an innovative software engineer and technical writer passionate about the developer community. I'm interested in building applications that run on the internet.

Building microservices with Node.js

5 min read 1429

Node Micro Service

Early on in the practice of software development, best practice involved tightly coupling all of the software’s components in what is known as a monolithic application. However, monolithic applications require extra effort to respond to changes in the system. If any particular component develops a fault, the entire system is affected.

Nowadays, we can solve the problem using microservices, which allow us to build our software product components separately. If there is a fault in one component, it won’t affect the functioning of the entire software product.

In this article, we’ll review the concept of microservices, learn how to implement a microservice with Node.js, and explore how microservices are changing the practice of software development. Let’s get started!

Prerequisites

To follow along with this article, you’ll need the following:

  • Node.js installed on your computer
  • Basic knowledge of JavaScript and Node.js

Microservices vs. monolithic applications

Understanding monolithic applications

A monolithic application is a single-tiered application in which all components are composed as one unit.

Imagine you’re building a library management system, and all of the components, like books, users, and their respective services and databases are fused together as one unit. If there is a fault in any one component, the entire system will need to be brought down to correct the error.

For this reason, monolithic applications are neither flexible nor easily scalable. You cannot build features concurrently or achieve continuous deployment. However, while monolithic applications are not cost-effective to manage, they are cost-effective to build. Developers recognized the need to create a system in which one faulty component wouldn’t affect the entire software system.

Understanding microservices

Microservices became necessary due to the shortcomings of the monolithic pattern of software development. In a microservice, each software application feature is separated from the other, in most cases with their respective servers and databases. Applications built with this kind of architecture are loosely coupled, also referred to as distributed applications.

Imagine we’re building an ecommerce store. We’ll need models for a payment feature, cart, customers, admin, and order. Each of these features will have its own separate servers and databases.

Our ecommerce microservices will communicate with each other using the REST API framework. With our store features developed independently from each other, we can easily identify which feature to debug if our system develops a fault and avoid having to bring down the entire application.

In contrast to monolithic applications, applications developed using microservices are scalable. You can use any programming language to develop a microservice; in fact, you can use different languages to develop different features in a microservice application.



Overall, microservices offer a better developer experience. A new developer joining the team won’t have to understand the entire code base, but rather only the features they are working on, increasing productivity. Lastly, unit testing is encouraged in microservices. A unit test can be written to test a particular functionality.

However, it’s important to keep in mind that building microservices requires expertise because integration and end-to-end testing can be very challenging. Additionally, microservices can become very bulky, causing high maintenance costs. Finally, it’s not always easy to migrate software already developed using monolithic architecture to a microservice, and it can be challenging for applications to locate each other within a complex network.

Using Node.js for our microservice

You can use any programming language, like Java, C#, or Python to develop a microservice, but Node.js is an outstanding choice for a few reasons.

For one, Node.js uses an event-driven architecture and enables efficient, real-time application development. Node.js single-threading and asynchronous capabilities enable a non-blocking mechanism. Developers using Node.js to build microservices have an uninterrupted flow, with Node.js code being fast, highly scalable, and easy to maintain.

Build a simple microservice application with Node.js

To illustrate how to develop microservices with Node.js, we’ll use the OpenWeather API service. First, create a free account.

Create a new folder on your computer, preferably on your desktop for easy access, and name it weathermicroservice. Open weathermicroservice in your code editor and confirm you have Node.js installed on your computer by running the command below:

node -v

If Node.js is not installed, go ahead and download it. In weathermicroservice, run the command below to initialize the package.json:

Run npm init or npm init -y

With npm init, you customize the setting or fields to create the package.json file. On the other hand, npm init -y uses the default setting or fields to create the package.json file.

Now, let’s install our required dependencies with the command below:

run npm install Express nodemon request

Now, your package.json file should look similar to the screenshot below:

Package JSON Node Microservice

Directly inside the main folder, create a file called server.js. Inside, write the following code:

// require express
const express = require("express");

//create an app using express constructor
const weatherApp = express();

// declare your port
const port = 5000;

// require routes from the routes.js file
const routes = require("./api/routes");
// set the route for our application by passing the app to the routes object
routes(weatherApp);

// call the listen method on the app
weatherApp.listen(port, ()=>{
    console.log("Server is running is port: " + port);
});

server.js is the main file for our microservice app, as indicated in our package.json file. Next, we’ll create another folder inside the weathermicroservice folder named api_source.

Inside the api_source folder, create two files named controller.js and routes.js. Inside the routes.js file, write the following code:

// create a controller object
const controller = require("./controller");

// declare a function and export it to be used in another file
module.exports = function(weatherApp){
    weatherApp.route("/about")
                .get(controller.about);
    weatherApp.route("/weather")
                .get(controller.getWeather);
};

The function takes weatherApp as a parameter and defines the routes for our application. weatherApp.route("/about") listens for a GET request on the /about endpoint.


More great articles from LogRocket:


This request is then handled by the about function in the controller.js file. The weatherApp.route("/weather") listens for a GET request on the /weather endpoint. The getWeather function handles the request.

Now that we’re done with the route module, it’s time to create the controllers to handle the GET request from the route module. Inside your controller.js file, write the following code:

// create a variable referencing to the package.json file
let properties = require("../package.json");

// create a variable and require the weather file inside the service folder
let weather = require("../service/weather");

// create an object
let controllers = {
    about: (req, res)=>{

//create an object and access the values in the package.json file
        let aboutInfo ={
            name: properties.name,
            description: properties.description,
            author: properties.author 
        }
// return the object in json format
        res.json(aboutInfo);
    },

//create a function
    getWeather: function(req, res){

//call the find method on the weather module
        weather.find(req, res, function(err, weath) {
            if(err)
                res.send(err);
             res.json(weath);
        });
    },
};

//export the controller module so it can be use in another file within the application
module.exports = controllers;

Inside the main folder, create another folder called service. Inside the service folder, create a file called weather.js, where we’ll connect to the external API.

Inside the weather.js file, write the following code:

// declare the request package we added to the package.json
let request = require("request");

// assign your api key and api url to a variable
const apiKey = "your own api key";
const apiUrl = "your api url as provided on your dashboard";

let weather = {
    find: (req, res, next)=>{
        request(apiUrl + apiKey + "/weather.json" + req.params.weather,
        function(error, response, body){

//check that there is no error
            if(!error && response.statusCode==200){
                response = JSON.parse(body);
                res.send(response);
            }else{
                console.log(response.statusCode + response.body);
                res.send("An error occurred, it could be from your api");
            }
        });
    }
};

//export the weather module 
module.exports = weather;

In the code above, we use the find function, which accepts three parameters, request, response, and next objects. The request object in line 10 accepts the URL of the service and defines a callback function to handle the response.

Conclusion

In this tutorial, we learned about the important differences between microservices and monolithic applications. We learned why Node.js is a great choice for building microservices, and we ran through an example using the OpenWeather API. Using a microservice offers flexibility and performance benefits that can’t be achieved with a monolithic application. The event-driven architecture of Node.js makes it a perfect choice for microservices, being fast, highly scalable, and easy to maintain.

200’s only Monitor failed and slow network requests in production

Deploying a Node-based web app or website is the easy part. Making sure your Node instance continues to serve resources to your app is where things get tougher. If you’re interested in ensuring requests to the backend or third party services are successful, try LogRocket. https://logrocket.com/signup/

LogRocket is like a DVR for web and mobile apps, recording literally everything that happens while a user interacts with your app. Instead of guessing why problems happen, you can aggregate and report on problematic network requests to quickly understand the root cause.

LogRocket instruments your app to record baseline performance timings such as page load time, time to first byte, slow network requests, and also logs Redux, NgRx, and Vuex actions/state. .
Frank Joseph I'm an innovative software engineer and technical writer passionate about the developer community. I'm interested in building applications that run on the internet.

5 Replies to “Building microservices with Node.js”

  1. Bro, you should attach your website and linkedin profile to your page. That way people can reach you with opportunties.

  2. Toi bad the most important part is not described. How do multiples microservice interact with each other. For exemple you call an endpoint this endpoint retreive data and call 2 other micro services that have coupled data in another db

  3. For a Node.js article, this felt pretty dated and out of touch. I guess my biggest gripe is that you’re promoting the use of request (which has been deprecated for a while now) but also some of the conventions used aren’t exactly the best. I also wish you’d explain microservices more in depth. Just some constructive criticism

Leave a Reply