NestJS Microservices Pattern
backend
TypeScript
architecture
strict_senior
Build microservices architecture with NestJS using message patterns and transports.
By olivia_c
12/8/2025
Prompt
NestJS Microservices Architecture
Build a microservices-based backend for [Application] using NestJS with message patterns and inter-service communication.
Requirements
1. Microservice Setup
Create [Number] microservices for:
- [Service 1] - [Responsibility] (e.g., User Service)
- [Service 2] - [Responsibility] (e.g., Order Service)
- [Service 3] - [Responsibility] (e.g., Notification Service)
2. Transport Layer
Choose and configure transport:
- TCP - For internal communication
- Redis - For pub/sub patterns
- RabbitMQ - For reliable messaging
- NATS - For high-performance messaging
- gRPC - For typed contracts
3. Message Patterns
Implement:
- Request-Response patterns for synchronous operations
- Event-based patterns for async notifications
- Message handlers with proper typing
- Error handling middleware
4. Service Communication
Configure:
- Client proxy injection
- Service registry/discovery
- Load balancing
- Circuit breakers
- Retry logic
5. Shared Code
Create shared modules for:
- Circuit breakers
5. Service Registration
Set up:
- Service discovery (if needed)
- Load balancing
- Health checks
- Graceful shutdown
Implementation Pattern
// Microservice bootstrap
import { NestFactory } from '@nestjs/core'
import { Transport, MicroserviceOptions } from '@nestjs/microservices'
async function bootstrap() {
const app = await NestFactory.createMicroservice<MicroserviceOptions>(
AppModule,
{
transport: Transport.[TRANSPORT_TYPE],
options: {
host: process.env.[SERVICE_HOST],
port: parseInt(process.env.[SERVICE_PORT])
}
}
)
await app.listen()
console.log('[ServiceName] microservice is listening')
}
bootstrap()
// Message Pattern Controller
import { Controller } from '@nestjs/common'
import { MessagePattern, Payload, Ctx, RpcException } from '@nestjs/microservices'
@Controller()
export class [ServiceController] {
constructor(private readonly [service]: [ServiceName]) {}
@MessagePattern({ cmd: '[command_name]' })
async [methodName](@Payload() data: [DataType], @Ctx() context: any) {
try {
return await this.[service].[operation](data)
} catch (error) {
throw new RpcException({
statusCode: 500,
message: error.message
})
}
}
@MessagePattern({ cmd: '[query_name]' })
async [queryMethod](@Payload() params: [ParamsType]) {
return await this.[service].[queryOperation](params)
}
}
// Client (API Gateway or another service)
import { Module } from '@nestjs/common'
import { ClientsModule, Transport } from '@nestjs/microservices'
@Module({
imports: [
ClientsModule.register([
{
name: '[SERVICE_NAME]',
transport: Transport.[TRANSPORT_TYPE],
options: {
host: process.env.[SERVICE_HOST],
port: parseInt(process.env.[SERVICE_PORT])
}
}
])
]
})
export class AppModule {}
// Using client in controller
import { Controller, Get, Inject } from '@nestjs/common'
import { ClientProxy } from '@nestjs/microservices'
@Controller('[resource]')
export class [ResourceName]Controller {
constructor(
@Inject('[SERVICE_NAME]') private client: ClientProxy
) {}
@Get()
async get[Resource]() {
return this.client.send(
{ cmd: '[command]' },
{ /* payload */ }
).toPromise()
}
@Post('[action]')
async [action](@Body() dto: [DtoType]) {
// Emit event (fire and forget)
this.client.emit('[event_name]', dto)
return { success: true }
}
}
Alternative Transports
Redis
{
transport: Transport.REDIS,
options: {
host: 'localhost',
port: 6379
}
}
RabbitMQ
{
transport: Transport.RMQ,
options: {
urls: ['amqp://localhost:5672'],
queue: '[queue_name]',
queueOptions: { durable: false }
}
}
Best Practices
- Use DTOs for type safety
- Implement proper error handling
- Add timeout handling
- Use health checks
- Implement circuit breakers
- Log all inter-service calls
- Version your message contracts
- Use message queues for reliability
Tags
nestjs
microservices
architecture
nodejs
Tested Models
gpt-4
claude-3-opus