What are microservices in NestJS?
What microservices are in NestJS
A microservice in NestJS is a separate application (or part of a system) that talks to other services not over HTTP, but through a message-based transport layer (a message broker).
Every microservice:
- is independent of the others;
- has its own data store;
- performs a tightly scoped function (e.g. Auth, Orders, Payments);
- communicates via transport protocols (TCP, Redis, RabbitMQ, Kafka, NATS, and others).
The core idea
Instead of direct HTTP requests like:
Auth → Users → Orders → PaymentsNestJS microservices interact through messages:
[Client] → (send message) → [Microservice]Each service listens for certain message patterns, and responds without knowing anything about how the other services are implemented.
A simple diagram
┌───────────────────┐ ┌────────────────────┐
│ Auth Microservice │◀────▶│ Users Microservice │
└───────────────────┘ └────────────────────┘
▲ ▲
│ │
▼ ▼
[Gateway API] ⇄ [Message Broker]Every service is wired together through a broker (e.g. Redis, RabbitMQ, or Kafka). If one of them goes down, the others keep working.
A microservice example in NestJS
The service
// math.service.ts
import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';
@Controller()
export class MathController {
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
return (data || []).reduce((a, b) => a + b);
}
}The module
import { Module } from '@nestjs/common';
import { MathController } from './math.controller';
@Module({
controllers: [MathController],
})
export class MathModule {}Bootstrapping the microservice
import { NestFactory } from '@nestjs/core';
import { Transport, MicroserviceOptions } from '@nestjs/microservices';
import { MathModule } from './math.module';
async function bootstrap() {
const app = await NestFactory.createMicroservice<MicroserviceOptions>(
MathModule,
{
transport: Transport.TCP, // RabbitMQ, Kafka, Redis, etc. can be chosen instead
options: { port: 4001 },
},
);
await app.listen();
}
bootstrap();The client (calling the microservice)
import { Controller, Get, Inject } from '@nestjs/common';
import { ClientProxy, ClientProxyFactory, Transport } from '@nestjs/microservices';
@Controller()
export class AppController {
private client: ClientProxy;
constructor() {
this.client = ClientProxyFactory.create({
transport: Transport.TCP,
options: { port: 4001 },
});
}
@Get()
async getSum() {
const result = await this.client.send({ cmd: 'sum' }, [1, 2, 3]).toPromise();
return { result }; // { result: 6 }
}
}Here client.send() sends the { cmd: 'sum' } message,
and the microservice listens for it via @MessagePattern({ cmd: 'sum' }).
Transport layers
NestJS supports several mechanisms for microservices to communicate:
| Transport | Purpose |
|---|---|
| TCP | A simple way to connect services within a network |
| Redis | A fast message broker with pub/sub |
| NATS | A lightweight, high-throughput message broker |
| RabbitMQ | Message queues, acknowledgments, routing |
| Kafka | Streaming data transfer |
| MQTT | IoT, lightweight devices |
| gRPC | High-performance RPC communication (protobuf) |
Principles of microservices in NestJS
| Principle | Description |
|---|---|
| Isolation | Each service is autonomous (has its own code, DB, config) |
| Message-based interaction | Asynchronous communication instead of HTTP |
| Resilience | One service failing doesn't break the whole system |
| Scaling | A specific microservice can be scaled independently |
| Clear responsibility | Each microservice handles a narrow business function |
An interaction pattern
Request-response (send / @MessagePattern)
The client sends a request and waits for a response.
client.send({ cmd: 'sum' }, [1, 2, 3])Event-based (emit / @EventPattern)
The client just fires an event, with no response expected.
client.emit('user_created', { id: 1, name: 'John' })@EventPattern('user_created')
handleUserCreated(data: any) {
console.log('New user:', data);
}When to use microservices
They're a good fit if:
- the project is large and spans different business domains;
- high scalability is needed;
- it matters to be able to deploy services independently;
- you want to use different technologies for different services;
- the system needs to stay resilient when individual components fail.
They're not a good fit if:
- the project is small, or a monolith is simpler to maintain;
- the added network complexity isn't justified;
- the team is small and doesn't need domains split apart.
An architecture example
┌─────────────┐ ┌─────────────┐
│ API Gateway │──────▶│ Auth Service│
│ (HTTP) │ │ (JWT/Auth) │
└─────────────┘ └─────────────┘
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Orders Svc │◀────▶│ Payments Svc│
└─────────────┘ └─────────────┘They all communicate through a message broker, not directly.
Summary
| Concept | Description |
|---|---|
| Microservices in NestJS | Independent parts of an application that communicate through messages |
| Main interface | @MessagePattern() / @EventPattern() |
| Transport layers | TCP, Redis, RabbitMQ, Kafka, NATS, MQTT, gRPC |
| Main advantages | Scalability, fault tolerance, isolation |
| Core principle | Asynchronous communication and loose coupling |
| Key classes | ClientProxy, ClientProxyFactory, MicroserviceOptions |
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.