Custom Transporters in NestJS
Last Updated :
30 Jul, 2024
NestJS is a progressive Node.js framework for building efficient, reliable, and scalable server-side applications. One of its powerful features is the microservices architecture, which allows developers to build distributed systems.
NestJS provides built-in transporters like TCP, Redis, and NATS, but sometimes you might need to create a custom transporter to meet specific requirements. This article explores how to create and use custom transporters in NestJS.
What are Transporters in NestJS?
Transporters in NestJS are responsible for communication between microservices. They abstract the underlying communication protocol, allowing developers to focus on business logic. NestJS provides several built-in transporters, but custom transporters can be created to use different protocols or integrate with specific services.
The built-in transporters are:
- TCP: Default transport layer, suitable for direct service-to-service communication.
- Redis: Used for Pub/Sub messaging patterns.
- NATS: Lightweight, high-performance messaging system.
- MQTT: Protocol for IoT and M2M communication.
- gRPC: Google’s RPC framework for microservices.
While these built-in transporters cover a wide range of use cases, there are situations where a custom transporter is necessary. For example, integrating with a legacy system or a third-party service with a unique protocol might require a custom solution.
When to Use a Custom Transporter
Creating a custom transporter might be necessary when:
- You need to integrate with a third-party service that uses a proprietary protocol.
- You want to optimize performance with a specialized communication protocol.
- The built-in transporters do not meet specific application requirements.
Steps to Create Nest Application
Step 1: Install NestJS globally in your system
To create a new NestJS project, you can use the NestJS CLI (@nestjs/cli). Install it globally using npm:
npm install -g @nestjs/cli
Step 2: Initialize NestJS Project
Creating a New NestJS Project using the below command
nest new nest-gfg
cd nest-gfg
You will be prompted to choose a package manager. Select either npm or yarn according to your preference.
Step 3: Install Required Packages
Install the @nestjs/microservices
package if it’s not already included:
npm install @nestjs/microservices
npm install @nestjs/platform-socket.io
npm install @nestjs/websockets
Step 4: Create the Custom Transporter
Create a new file custom.transporter.ts
and app.gateway.ts in the src
directory.
Folder Structure
Nestjs folder structureDependencies
"dependencies": {
"@nestjs/common": "^10.0.0",
"@nestjs/core": "^10.0.0",
"@nestjs/microservices": "^10.3.10",
"@nestjs/platform-express": "^10.0.0",
"@nestjs/platform-socket.io": "^10.3.10",
"@nestjs/websockets": "^10.3.10",
"reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1"
}
Example: Creating Custom Transporter
JavaScript
//src/custom.transporter.ts
import {
ClientProxy,
ReadPacket,
WritePacket,
CustomTransportStrategy,
} from '@nestjs/microservices';
import { Logger } from '@nestjs/common';
export class CustomTransporter
extends ClientProxy
implements CustomTransportStrategy {
private readonly logger = new Logger(CustomTransporter.name);
constructor(private readonly options: any) {
super();
}
async connect(): Promise<void> {
this.logger.log('Custom Transporter connected...');
// Implement your connection logic here
}
async close(): Promise<void> {
this.logger.log('Custom Transporter closed...');
// Implement your close logic here
}
listen(callback: () => void): void {
this.logger.log('Custom Transporter is listening...');
// Implement your custom transport logic here
callback();
}
protected dispatchEvent(packet: ReadPacket<any>): Promise<any> {
this.logger.log(`Dispatch event: ${JSON.stringify(packet)}`);
// Implement your dispatch event logic here
return Promise.resolve();
}
protected publish(
packet: ReadPacket<any>,
callback: (packet: WritePacket<any>) => void,
): () => void {
this.logger.log(`Publish event: ${JSON.stringify(packet)}`);
// Simulate an immediate response for testing purposes
callback({ response: 'response' });
return () => { };
}
}
JavaScript
//main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { CustomTransporter } from './custom.transporter';
import { MicroserviceOptions } from '@nestjs/microservices';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.connectMicroservice<MicroserviceOptions>({
strategy: new CustomTransporter({
/* Custom options */
}),
});
await app.startAllMicroservices();
await app.listen(3000);
}
bootstrap();
JavaScript
//app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AppGateway } from './app.gateway';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService, AppGateway],
})
export class AppModule { }
JavaScript
//app.controller.ts
import { Controller, Get } from '@nestjs/common';
import {
ClientProxy,
ClientProxyFactory,
CustomClientOptions,
} from '@nestjs/microservices';
import { CustomTransporter } from './custom.transporter';
@Controller()
export class AppController {
private client: ClientProxy;
constructor() {
const customClientOptions: CustomClientOptions = {
customClass: CustomTransporter,
options: {
/* Custom options */
},
};
this.client = ClientProxyFactory.create(customClientOptions);
}
@Get()
async sendMessage() {
const pattern = { cmd: 'custom_message' };
const data = { text: 'Hello from custom transporter' };
const response = await this.client.send(pattern, data).toPromise();
return response;
}
@Get('custom-message')
async getCustomMessage() {
const pattern = { cmd: 'custom_message' };
const data = { text: 'Hello from custom transporter' };
const response = await this.client.send(pattern, data).toPromise();
return response;
}
}
JavaScript
//app.gateway.ts
import {
SubscribeMessage,
WebSocketGateway,
MessageBody,
} from '@nestjs/websockets';
@WebSocketGateway()
export class AppGateway {
@SubscribeMessage('message')
handleMessage(@MessageBody() message: string): string {
return message;
}
}
JavaScript
//app.service.ts
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
}
To start the application run the following command.
npm run start
Output
Custom Transporters in NestJS
Similar Reads
Pipes in NestJS
Pipes in NestJS help in transforming and validating data within your application. They play an important role in ensuring that data entering the system is clean, consistent, and meets the required criteria. In this article, we will explore how pipes work in NestJS, their benefits, and how to impleme
3 min read
How To Perform Unit Test in NestJS?
NestJS is a Node.js framework for building efficient, reliable and scalable server-side applications. It is built using TypeScript and It offers support for unit testing through the Jest testing framework. In this article, we will learn about performing unit testing in a NestJs.Table of ContentWhat
5 min read
Using WebSockets in NestJS
WebSocket is a protocol used for real-time communication between client and server. It is a better approach to serve real-time data than short-polling and long-polling.In this article, we will be building a simple real-time Chat Application using Socket.io which is a JavaScript library used to imple
3 min read
How To Use Query Parameters in NestJS?
NestJS is a popular framework for building scalable server-side applications using Node.js. It is built on top of TypeScript and offers a powerful yet simple way to create and manage APIs. One of the core features of any web framework is handling query parameters, which allow developers to pass data
6 min read
Guards in NestJS
NestJS is an extensible framework for building server-side applications using TypeScript. One of its key features is the ability to implement guards, which provide a way to intercept and control the flow of incoming requests to routes. Guards are used to implement authorization logic, ensuring that
2 min read
Nested Dictionary in TypeScript
TypeScript is a powerful, statically typed superset of JavaScript that offers robust features for building large-scale applications. One of its features is the ability to handle complex data structures, such as nested dictionaries. In this article, we'll explore what nested dictionaries are, how to
4 min read
Controllers in NestJS
NestJS is a Node.js framework for building efficient, reliable, and scalable server-side applications. One of its core concepts is the use of controllers. Controllers in NestJS are responsible for handling incoming requests, processing them, and returning responses to the client. In this article, we
4 min read
Optimize Your NestJS Applications
NestJS is a popular framework for building scalable and maintainable server-side applications with Node.js. NestJS offers many out-of-the-box features to enhance performance. In this article, we will cover several key techniques, tools, and best practices to ensure your NestJS application runs effic
4 min read
How To Write Integration Tests in NestJS?
Integration testing is an important part of software development, ensuring that various parts of your application work together as expected. In NestJS, integration testing allows you to test the interaction between different modules, services, and controllers. In this article, we will guide you thro
8 min read
NestJS Enable Cors In Production
Cross-Origin Resource Sharing (CORS) is a security feature implemented by browsers to restrict web pages from making requests to domains other than the one from which they were originally served. While CORS is critical for preventing unauthorized data access, it often needs to be configured properly
5 min read