How do Microservices work in NestJS?
NestJS Microservices
NestJS provides a powerful microservices module that supports multiple transport layers for inter-service communication beyond HTTP.
Transport Layers
| Transport | Package | Use Case |
|---|---|---|
| TCP | Built-in | Simple microservices |
| Redis | @nestjs/microservices | Pub/Sub, event-driven |
| NATS | @nestjs/microservices | High-performance messaging |
| RabbitMQ | @nestjs/microservices | Complex routing, reliability |
| Kafka | @nestjs/microservices | Event streaming, high throughput |
| gRPC | @nestjs/microservices | Type-safe, high-performance |
Creating a Microservice (TCP)
Service (Microservice)
typescript
// math-service/main.ts
import { NestFactory } from '@nestjs/core';
import { Transport, MicroserviceOptions } from '@nestjs/microservices';
async function bootstrap() {
const app = await NestFactory.createMicroservice<MicroserviceOptions>(
AppModule,
{
transport: Transport.TCP,
options: { host: '0.0.0.0', port: 3001 },
},
);
await app.listen();
}
bootstrap();Controller with Message Patterns
typescript
import { Controller } from '@nestjs/common';
import { MessagePattern, EventPattern, Payload } from '@nestjs/microservices';
@Controller()
export class MathController {
// Request-Response pattern
@MessagePattern({ cmd: 'sum' })
sum(@Payload() data: { numbers: number[] }): number {
return data.numbers.reduce((a, b) => a + b, 0);
}
// Event-based pattern (fire and forget)
@EventPattern('order_created')
handleOrderCreated(@Payload() data: { orderId: string }) {
console.log('Processing order:', data.orderId);
}
}Client (API Gateway)
typescript
// api-gateway/app.module.ts
import { Module } from '@nestjs/common';
import { ClientsModule, Transport } from '@nestjs/microservices';
@Module({
imports: [
ClientsModule.register([
{
name: 'MATH_SERVICE',
transport: Transport.TCP,
options: { host: 'math-service', port: 3001 },
},
]),
],
})
export class AppModule {}typescript
import { Controller, Get, Inject } from '@nestjs/common';
import { ClientProxy } from '@nestjs/microservices';
@Controller('math')
export class MathController {
constructor(
@Inject('MATH_SERVICE') private readonly mathClient: ClientProxy,
) {}
@Get('sum')
async getSum() {
// Request-Response
const result = await this.mathClient
.send({ cmd: 'sum' }, { numbers: [1, 2, 3, 4, 5] })
.toPromise();
return { result };
}
@Post('order')
async createOrder() {
// Event (fire and forget)
this.mathClient.emit('order_created', { orderId: 'abc123' });
return { status: 'sent' };
}
}Using Redis Transport
typescript
// Service
const app = await NestFactory.createMicroservice(AppModule, {
transport: Transport.REDIS,
options: {
host: 'localhost',
port: 6379,
},
});
// Client
ClientsModule.register([{
name: 'NOTIFICATIONS_SERVICE',
transport: Transport.REDIS,
options: { host: 'localhost', port: 6379 },
}]);Hybrid Application (HTTP + Microservice)
typescript
const app = await NestFactory.create(AppModule);
// Connect microservice transport alongside HTTP
app.connectMicroservice({
transport: Transport.REDIS,
options: { host: 'localhost', port: 6379 },
});
await app.startAllMicroservices();
await app.listen(3000);Communication Patterns
| Pattern | Method | Description |
|---|---|---|
| Request-Response | @MessagePattern() / client.send() | Send and wait for reply |
| Event-based | @EventPattern() / client.emit() | Fire and forget |
Architecture Example
βββββββββββββββββββ
β API Gateway β
β (HTTP + REST) β
ββββββββββ¬βββββββββ
β
ββββββββββββββββΌβββββββββββββββ
β β β
βββββββββββΌββββ ββββββββΌβββββββ βββββΌββββββββββ
β User Service β βOrder Serviceβ βNotification β
β (TCP) β β (RabbitMQ) β β (Redis) β
βββββββββββββββ βββββββββββββββ ββββββββββββββββTip: Start with a monolith using NestJS modules. Extract into microservices only when you need independent scaling, deployment, or team boundaries. NestJS makes this transition smooth thanks to its modular architecture.
Short Answer
Interview readyPremium
A concise answer to help you respond confidently on this topic during an interview.