Quick Summary:

Leveraging Node js microservices provides modern and adequate applications for unexpected challenges and changes. In this blog, you understand what microservices are, why they should be integrated with nodejs, and how to build them with nodejs for efficient applications.

Table of Contents

Introduction

Since there is a spike in a demand for modern and scalable applications, the popularity of Microservice has also gained equal momentum. All thanks to the efficient programing language that makes it possible. Several organizations have already leveraged Node js Microservices to build applications, like Netflix, Walmart, PayPal, and Trello.

Now, why do these organizations opt for Microservices using Node.js, and how it could benefit you is where this article becomes your helping hand.

This blog unfolds the benefits of using NodeJs for building microservices for your applications. Before jumping into the node js microservices tutorial, let’s first understand microservices.

Understanding Node js Microservices Architecture and How It Works

Microservice is an application architecture that breaks down complex applications into single, manageable services. It is a software architecture approach where independent components communicate with each other to provide efficient functionality.

Each service interacts with other services through well-defined APIs. Every microservice is loosely coupled with the explicit purpose of making building and managing applications more accessible.

Microservices allow agility in the development, testing, and deployment of service, making each service function independently.

Monolithic vs microservices in NodeJs

Additionally, microservices come as a solution for the old monolithic systems. Monolithic systems are contrary to microservices, as it is one unit with all functions. In simple terms, it is a single program that is responsible for performing all parts and services of an application.

Thus, monolithic applications are time-consuming and complex to modify whereas microservices can be modified easily.

When it comes to developing powerful applications, Node js is often a good fit. NodeJs is an event-driven JavaScript framework designed to handle asynchronous I/O and manage significant traffic.

By integrating Node js microservices architecture, you can create dynamic applications that are fast, easy to manage, and flexible.

Why Use Microservices With Node.js?

Node Js’s quick speed, responsiveness, and resilience make it an excellent choice for building microservices that need to respond quickly to requests and handle errors. Also, by leveraging the advantage of both microservices and Node js, you can efficiently match your users and business needs.

Benefits of Using Node js and Microservices

Here are numerous benefits of using Nodejs microservice architecture for software or app development services.

🟠 Enhanced Scalability
Using microservice NodeJs improves applications’ scalability by breaking them down into small and independent components. Node js is an ideal technology because it is event-driven architecture and a non-blocking I/O model. With microservice in Nodejs, you can manage numerous large requests simultaneously.

🟠 Diverse Technology
Microservices architecture allows for efficient technology diversity which adds value to the building and managing of complex applications. Using microservices in Node Js, you can make rapid changes by implementing different services and methods. With different technologies and small components, it makes it easier to integrate with other systems.

🟠 Increase Resilience
Microservices can be developed and deployed independently, hence you can modify and update single services without affecting the rest of the application. Also, each service handles failure and recovers it instantly. Nodejs has built-in error-handling mechanisms that help to develop more resilient microservices.

🟠 Resource Allocation
With Node js microservices, you can easily allocate resources based on the particular requirements of the project or services. For instance, if a service requires more processing memory or process, you can assign it at that moment. Also, it will help to save resources, optimize them, and decrease costs.

🟠 Better Performance
By breaking down and use of powerful technology, you can leverage efficient performance for the applications. It becomes easier to roll out changes, fix bugs, and optimize service faster without affecting the rest of the applications. Achieving specific requirements will improve overall response time and application performance.

Microservices with Node.js Example

In this demo application, we will build microservices with NodeJS which will connect to an external API.

The app will have three services: Book, Customer, and Order services. Each of the services will have individual servers running on different ports. These services will communicate with each other through REST APIs. We all know that if it wasn’t microservices architecture we would have only one server running. But, in microservices architecture the scenario is different.

So, this was about what we are building in this tutorial, let’s get started with the coding part.

Ready to streamline your operations and improve your bottom line?
Connect with us to hire Node js developer today and start building microservices that can handle even the busiest workloads.

Building Microservices in Node js

Step 1: Initial Set-Up

Make sure you have Node.js installed. Visit Nodejs.org to download the latest Node version, if your system doesn’t have Node.js.

Run npm init in the project root folder. This will create a package.json file that will create certain questions about the package, if you are not sure how to respond you can use the default.

We will use four packages, Express, mongoose, axios, and dotenv which can be installed as follows:

Copy Text
$ npm install express mongoose axios dotenv --save

Project Structure

Refer to the below image for the project structure. The structure can vary from person to person.

Microservices with Node.js Project Structure

Step 2: Creating Database Connection

Let’s start with the basic step to establish a DB connection. In the db folder, create a db.js to code to connect the database. This is just a small demo app, but the large and complex applications also have different databases for individual services.

// db.js

Copy Text
const mongoose = require('mongoose');
mongoose.connect(process.env.MONGO_URI, { 
     useNewUrlParser: true,
     useUnifiedTopology: true,
     useFindAndModify: false,
     useCreateIndex: true
}).then(() => {
     console.log('Connection successful!');
}).catch((e) => {
     console.log('Connection failed!');
})

In db.js, we have to require a mongoose package for MongoDB database connection.

The function connect() will take two arguments – uri and options.

Step 3: Creating Book Service

Create a Book folder for Book service, inside the Book folder we will create Book.js for creating a Book Model.

// Book.js

Copy Text
const mongoose = require('mongoose');
const bookSchema = mongoose.Schema({
  title: {
     type: String,
     require: true
   },
   author: {
      type: String,
      require: true
   },
   numberPages: {
       type: Number,
       require: false
   },
   publisher: {
       type: String,
       require: false
   }
})

const Book = mongoose.model("book", bookSchema);

module.exports = Book;

Now we will need to create a server for the Book service.

Create a Server for Book Service

Create books.js inside the Book folder. Since we are learning to build microservices we will have different servers for services.

// books.js

Copy Text
require("dotenv").config();
const express = require('express');

// Connect
require('../db/db');

const Book = require('./Book');

const app = express();
const port = 3000;
app.use(express.json())

app.post('/book', (req, res) => {
    const newBook = new Book({...req.body});
    newBook.save().then(() => {
          res.send('New Book added successfully!')
    }).catch((err) => {
         res.status(500).send('Internal Server Error!');
    })
})

app.get('/books', (req, res) => {
   Book.find().then((books) => {
        if (books.length !== 0) {
              res.json(books)
        } else {
            res.status(404).send('Books not found');
       }
    }).catch((err) => {
         res.status(500).send('Internal Server Error!');
    });
})
app.get('/book/:id', (req, res) => {
    Book.findById(req.params.id).then((book) => {
        if (book) {
           res.json(book)
        } else {
            res.status(404).send('Books not found');
        }
     }).catch((err) => {
        res.status(500).send('Internal Server Error!');
    });
})
app.delete('/book/:id', (req, res) => {
    Book.findOneAndRemove(req.params.id).then((book) 	=> {
        if (book) {
             res.json('Book deleted Successfully!')
        } else {
            res.status(404).send('Book Not found!'); 
        }
    }).catch((err) => {
         res.status(500).send('Internal Server Error!');
    });
});
app.listen(port, () => {
     console.log(`Up and Running on port ${port} - This is Book service`);
})

We have used express for creating a server, made the db file required for connecting with the database, and Book model to storing data for Node performance.

The Book service has four routes:

  • Add books
  • Get all the books from the database
  • Get a particular book
  • Delete a book

Run book service at port 3000.

Step 4: Creating Customer Service

Create a Customer folder for Customer service, inside the Customer folder we will have Customer.js for model, just like we did for Book service in the previous section.

// Customer.js

Copy Text
const mongoose = require('mongoose');
const CustomerSchema = mongoose.Schema({
    name: {
       type: String,
       require: true
    },
    age: {
       type: Number,
       require: true
    },
    address: {
      type: String,
      require: true
    }
})
const Customer = mongoose.model("customer", CustomerSchema);

module.exports = Customer;

Now we will need to create a server for Customer service.

Create a Server for Customer Service

We will have a separate server for Customer service as well. Create a file named customer.js.

// customer.js

Copy Text
require("dotenv").config();
const express = require('express');

// Connect
require('../db/db');

const Customer = require('./Customer');

const app = express();
const port = 5000;
app.use(express.json())

app.post('/customer', (req, res) => {
    const newCustomer = new Customer({...req.body});
    newCustomer.save().then(() => {
       res.send('New Customer created successfully!');
    }).catch((err) => {
        res.status(500).send('Internal Server Error!');
    })
})
app.get('/customers', (req, res) => {
    Customer.find().then((customers) => {
       if (customers) {
          res.json(customers)
       } else {
          res.status(404).send('customers not found');
       }
    }).catch((err) => {
         res.status(500).send('Internal Server Error!');
   });
})

app.get('/customer/:id', (req, res) => {
    Customer.findById(req.params.id).then((customer) => 	{
     if (customer) {
          res.json(customer)
      } else {
          res.status(404).send('customer not found');
      }
    }).catch((err) => {
          res.status(500).send('Internal Server Error!');
   });
})

app.delete('/customer/:id', (req, res) => {
Customer.findByIdAndRemove(req.params.id).then((customer) => {
    if (customer) {
         res.json('customer deleted Successfully!')
      } else {
         res.status(404).send('Customer Not Found!');
      }
    }).catch((err) => {
       res.status(500).send('Internal Server Error!');
  });
});

app.listen(port, () => {
    console.log(`Up and Running on port ${port}- This is Customer service`);
})

Create the same four routes for Customer service as we did for the Book service

Run Customer service at port 5000.

Step 5: Creating Order Service

Create an Order.js file inside the Order folder for model, just like we did for Book and Customer service.

// Order.js

Copy Text
const mongoose = require('mongoose');

const orderSchema = mongoose.Schema({
    customerID: {
       type: mongoose.SchemaTypes.ObjectId,
       require: true
     },
     bookID: {
       type: mongoose.SchemaTypes.ObjectId,
       require: true
     },
     initialDate: {
        type: Date,
        require: true
     },
     deliveryDate: {
        type: Date,
        require: false
     }
})

const Order = mongoose.model("order", orderSchema);

module.exports = Order;

Now we will need to create a server for the Order service.

Create a Server for Order Service

Create order.js inside the Order folder.

// order.js

Copy Text
require("dotenv").config();
const express = require('express');
const mongoose = require("mongoose");
const axios = require('axios');

// Connect
require('../db/db');

const Order = require('./Order');

const app = express();
const port = 9000;
app.use(express.json())
app.post('/order', (req, res) => {
   const newOrder = new Order({
   customerID: mongoose.Types.ObjectId(req.body.customerID),
   bookID: mongoose.Types.ObjectId(req.body.bookID),
   initialDate: req.body.initialDate,
   deliveryDate: req.body.deliveryDate
});
newOrder.save().then(() => {
   res.send('New order added successfully!')
  }).catch((err) => {
   res.status(500).send('Internal Server Error!');
  })
})
app.get('/orders', (req, res) => {
   Order.find().then((orders) => {
      if (orders) {
          res.json(orders)
       } else {
          res.status(404).send('Orders not found');
       }
   }).catch((err) => {
          res.status(500).send('Internal Server Error!');
   });
})

app.get('/order/:id', (req, res) => {
    Order.findById(req.params.id).then((order) => {
       if (order) {
          axios.get(`http://localhost:5000/customer/${order.customerID}`).then((response) => {
         let orderObject = { 
           CustomerName: response.data.name, 
           BookTitle: '' 
          }
        axios.get(`http://localhost:3000/book/${order.bookID}`).then((response) => {
         orderObject.BookTitle = response.data.title 
         res.json(orderObject);
        })
   })	
     } else {
        res.status(404).send('Orders not found');
     }
    }).catch((err) => {
        res.status(500).send('Internal Server Error!');
   });
}) 

app.listen(port, () => {
     console.log(`Up and Running on port ${port} - This is Order service`);
})

Run customer service at port 9000.

We will create three routes in Order service:

  • Add an order. You need to pass bookId, customerId, initialDate, and deliveryDate for it.
  • Get all the orders from the database
  • Get customers and book details for a particular order.

To run the last route make sure all the services are running in the background. Because we are getting details from book service and customer service as well.

So, this was a step-by-step guide to build microservices with Node.js. The entire source code is available here: nodejs-microservices-example

Conclusion

Hence, microservices in NodeJs are a well-suitable match for developing applications. Also, it is ideal because both have the same approach and purpose: to grow faster and more scalable applications.

Using Node js in microservices allows you to develop a software application in numerous methods and technologies. In microservices With Nodejs, you can modify and update any changes without affecting any process.

We hope your purpose for visiting the tutorial has served the way you expected. If you want to avail the benefits of Nodejs microservices for your next project, you can contact the Node.js development company to develop a flexible application.

Frequently Asked Questions (FAQs)

Node js microservices architecture communicates with each other through numerous mechanisms, including message brokers, RESTful APIs, event-driven architecture, gRPC, GraphQL, and API HTTP service. However, the choice of communication depends on the requirement of the project.

Following are the Nodejs microservices frameworks to provide structured and dynamic applications:

  • Express js: Provides flexible features to handle HTTP requests and responses.
  • Nest js: A modular architecture with a set of built-in features, such as caching and routing.
  • Seneca: Toolkit that provides a set of patterns and plugins; focuses on passing messages.
  • LoopBack: Model-driven approach for building APIs and microservices. It helps to handle authorization, authentication, and data persistence.
  • Hapi.js: Extensive framework that provides a modular architecture, and built-in support for validation and authentication.

Service dependency, performance issues because of distribution, data consistency, additional operational overhead, and security concerns are some of the drawbacks of using microservices.

Yes, following the best practices for Nodejs microservices develops efficient applications:

  • Use an API gateway
  • Choose a lightweight framework
  • Focus on a small task
  • Implement performance monitoring, testing, and deploying
  • Utilize asynchronous programming

Get ahead of the competition by embracing Node.js microservices

By adopting this powerful technology, you can create a more efficient and scalable infrastructure that can handle the demands of today’s digital landscape.

Connect Now

Build Your Agile Team

Hire Skilled Developer From Us

Subscribe for
weekly updates

newsletter

What Makes Bacancy Stand Out?

  • Technical Subject Matter Experts
  • 2500+ Projects Completed
  • 90% Client Retention Ratio
  • 12+ Years of Experience

Our developers primarily focus on navigating client's requirements with precision. Besides, we develop and innovate to deliver only the best solutions to our clients.

get in touch
[email protected]

Your Success Is Guaranteed !

We accelerate the release of digital product and guaranteed their success

We Use Slack, Jira & GitHub for Accurate Deployment and Effective Communication.

How Can We Help You?