Development

Microservices with NodeJs Using NestJs Part 1


Introduction

Creating new server-side applications with node js requires a lot of dynamic programming where application size grows bigger and bigger over the period. Introducing new features and fixing the bugs in existing applications gets tedious over the period. To meet the business needs for growing applications becomes challenging to tackle. Introducing new members/developers to grow faster often risks unintentionally manipulating existing functionality. A better approach is to split your applications into small modules. This is where microservices come into the picture.

What are microservices?

Microservices is an architecture(service-oriented architecture) (SOA). In this architecture, applications are broken down into various services. The motivation behind this is separation and modularity.

Unlike monolithic architecture, microservices are more beneficial.
We don’t need to specify all business logic into a single software module which leads to complexity and time consuming while debugging.

A few Advantages of microservices are

  • Increases scalability
  • More flexibility
  • Modular architecture
  • Ease of introducing new features
  • More reliable and robust structure
monolithic architecture
Monolithic Architecture
microservices architecture

Why NodeJs for microservices?

Highly enriched runtime with various javascript modules, Node JS based on single-threaded architecture works with event loop with non-blocking io. Event-driven architecture and high scalability make it an excellent choice for microservices architecture.

Why Node + NestJs for microservices?

Nest (NestJS) is a framework for building efficient, scalable Node JS server-side applications. It uses progressive JavaScript, is built with and fully supports TypeScript (yet still enables developers to code in pure JavaScript) and combines elements of OOP (Object Oriented Programming), FP (Functional Programming) and FRP (Functional Reactive Programming).

It will be easy for you to work with Nest JS if you have worked with the Angular framework due to many similarities.

If you’re not familiar with Node JS, you can always visit the official site NestJS Docs for more information.

So enough talk about microservices architecture, let’s get our hands dirty and jump into code.

To start with, you need to install Nest JS CLI, use the following command for the same

$ npm i -g @nestjs/cli

We’ll create two nest js projects using Nest JS CLI to understand microservices architecture. Create a directory in your system and use the following commands to create both projects.

$ nest new micro-server

Nest JS Cli asks you to use the package manager for your application. You can choose any of your choices, for this tutorial we’ll choose yarn.
Nest JS CLI automatically sets up the base structure for you. You can use the command.

$ yarn start:dev

To test the application, you can head over to the browser and type the following in ‘http://localhost:3000’.

This is a simple REST API implementation demo application.

Now we’ll convert those monolithic applications into microservices. For same, supported transports in Nest JS are

  • Basic TCP (Direct Communication)
  • Redis (Message Broker)
  • MQIT (Message Broker)
  • NATS (Message Broker)
  • RabbitMQ (Message Broker)
  • gRPC (Remote Procedure Call)

As above, you can see, available transports are categorized into three categories as Direct Communication, Message Broker and Remote Procedure Call.
In PART-1, we’ll focus on Direct Communication i.e. TCP transport. In that, we’ll cover Event-based and Message Pattern communication.
Let’s start with event-driven communication. For the same, we’ll set up our server first. Open the code editor of your choice and install nest js microservices dependency as follows.

Event Driven Communication

$ yarn add @nestjs/microservices

Now we’ll jump into code changes, make the following changes to your main.ts filehttps://medium.com/media/3bae8717d21c083e3cc40a23052abd8a

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
// Create microservice config options
const microserviceOptions : MicroserviceOptions = {
transport: Transport.TCP,
options: {
host: '127.0.0.1',
port: 3000
},
};
async function bootstrap() {
const app = await NestFactory.createMicroservice<MicroserviceOptions>(
AppModule,
microserviceOptions
);
await app.listen();
}
bootstrap();

In the above changes, we created a microservice and used TCP as a transporter. To create a microservice in Nest, we can pass options as a second param, which contains the host and port you want to expose to run your microservice.
Also, change your app.controller.ts as

import { Controller, Get } from '@nestjs/common';
import { EventPattern } from '@nestjs/microservices';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@EventPattern('log_message')
async handleMessagePrinted(data: Record<string, unknown>) {
this.appService.logMessage(data.text)
}
}

Here, we’ve replaced the Rest API implementation with an event pattern. Our service will listen to any event named ‘log_message’ and log messages from that event into the console.

Also, change your app.service.ts as

import { Injectable, Logger } from '@nestjs/common';
const logger = new Logger('ServerAppService');
@Injectable()
export class AppService {
logMessage(message): void {
logger.log(message);
}
}

Here, we log that message to the console in the micro-server application. We have created a logger instance to log messages

And we’re all set, we have configured microservice, but wait we need to create a client to communicate with it, so let’s start. We’ll create a new nest js application and convert it to a client. Go back to the parent directory and fire the following command

$ nest new micro-client

Nest JS will create a new application for you, let’s add a microservices library to it.

$ yarn add @nestjs/microservices

Make changes to your app.controller.ts as follows in the new client app

import { Controller, Get, Inject, Logger } from '@nestjs/common';
import { ClientProxy } from '@nestjs/microservices';
const logger  = new Logger("ClientAppController");
@Controller()
export class AppController {
constructor(@Inject('LOGGER_SERVICE') private readonly client:   ClientProxy) { }
async onApplicationBootstrap() {
await this.client.connect();
}
@Get()
emitMessage() {
logger.log("In Microservice Client");
this.client.emit<any>('log_message', {text : 'Service Communicating'});
}
}

Here, we use the ClientProxy service in our controller to emit an event with a message. We’ll be registering that service in main.ts

Make changes to your app.module.ts as follows in the new client app

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { Transport, ClientsModule } from '@nestjs/microservices';
@Module({
imports: [
ClientsModule.register([
{ name: 'LOGGER_SERVICE', transport: Transport.TCP },
]),
],
controllers: [AppController],
providers: [],
})
export class AppModule {}

In AppModule, we register the client for our service and set transport like TCP.

And that’s it, you’re ready to test your first microservice application.
Don’t forget to run your microservice server and client app by going into both directories, micro-server, micro-client and type the following to get both of them running

$ yarn install
$ yarn start:dev

You can head over to the browser and type the following in ‘http://localhost:3000’ to test the application and you can see the magic. You’ll see the message ‘Service Communicating’ we are sending from the client, which will be printed in the micro-server application console. So the client can communicate with the microservice we have developed.

If you’re not able to figure where you have to make code changes to get both applications running and communicating, then you can head over to https://github.com/abhay-321/nestjs-microservices/tree/feature/event-pattern-communication and see code changes over there.

But this communication is one way to send messages from client to service but not get any response back.
This type of implementation is useful in logging messages to servers and similar applications.

For getting responses back, we can use the Message pattern, for that we need to make simple code changes as above, you can get the application code base here.
https://github.com/abhay-321/nestjs-microservices/tree/feature/message-pattern-communication

I hope this article gives you exposure to microservices and helps you create your first microservice application.
In Part 2, we’ll explore Microservices communication via message broker and we’ll use Redis as a message broker and its advantages over other message brokers.

Thanks for reading, we’ll continue in PART-2 🙂
To learn microservices along with Redis, please visit Microservices with NodeJs Using NestJs RedisOverviewmedium.com


For any questions and inquires, visit us on https://thinkitive.com/

Tags

Abhay Ahire

Software Engineer @Thinkitive

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button
Close