This episode covers the microservices architecture in NestJS: core microservices concepts, the TCP Redis NATS RabbitMQ and Kafka transport layers, gateway patterns and API composition, plus inter-service authentication and message validation.

As an application grows, building one large monolith becomes hard to maintain. Microservices break the application into small services that communicate over the network. NestJS has had mature microservices support from the very beginning.
Episode 14 covers the NestJS microservices architecture: concepts, transport layers, gateways, and inter-service security aspects.
Microservices split the application into several independent services — for example user-service, order-service, and payment-service. Each service has its own database and communicates over the network. NestJS supports this pattern through the @nestjs/microservices module.
NestJS microservices communicate using two patterns:
import { Controller } from "@nestjs/common";
import { MessagePattern, Payload } from "@nestjs/microservices";
@Controller()
export class UserController {
@MessagePattern("user.find")
find(@Payload() data: { id: number }): string {
return `User dengan id ${data.id}`;
}
}@MessagePattern("user.find") registers a handler that responds to a message named user.find.
NestJS supports several transport layers for inter-service communication:
Bootstrap the service with the transport of your choice:
import { NestFactory } from "@nestjs/core";
import { MicroserviceOptions, Transport } from "@nestjs/microservices";
import { UserModule } from "./user.module";
async function bootstrap(): Promise<void> {
const app = await NestFactory.createMicroservice<MicroserviceOptions>(
UserModule,
{
transport: Transport.TCP,
options: { host: "0.0.0.0", port: 3001 },
},
);
await app.listen();
}
void bootstrap();This service listens for TCP connections on port 3001.
const app = await NestFactory.createMicroservice<MicroserviceOptions>(
UserModule,
{
transport: Transport.REDIS,
options: { host: "localhost", port: 6379 },
},
);With Redis, messages are sent over pub-sub channels. Other options like NATS, RabbitMQ, and Kafka use similar configuration with their own options.
A gateway is a single entry point that forwards requests to the right service:
import { Controller, Get, Inject } from "@nestjs/common";
import { ClientProxy } from "@nestjs/microservices";
@Controller("users")
export class GatewayController {
constructor(
@Inject("USER_SERVICE") private readonly userClient: ClientProxy,
) {}
@Get(":id")
find(@Param("id") id: number): Promise<unknown> {
return this.userClient.send("user.find", { id }).toPromise();
}
}The gateway receives the HTTP request and forwards it as a message to the service. This is called API composition — the gateway coordinates several services for a single response.
To use ClientProxy, register the client in the module:
import { Module } from "@nestjs/common";
import { ClientsModule, Transport } from "@nestjs/microservices";
@Module({
imports: [
ClientsModule.register([
{
name: "USER_SERVICE",
transport: Transport.TCP,
options: { port: 3001 },
},
]),
],
})
export class GatewayModule {}When services communicate, make sure they trust each other. A common pattern: send a service token (not a user token) or use mTLS. NestJS lets you use an interceptor to add the token before sending a message:
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from "@nestjs/common";
import { Observable } from "rxjs";
@Injectable()
export class ServiceAuthInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {
const request = context.switchToHttp().getRequest();
request.headers["x-service-token"] = process.env.SERVICE_TOKEN;
return next.handle();
}
}Just like HTTP, messages between services must be validated. Use ValidationPipe on microservices handlers and DTOs for message payloads. This prevents corrupted or malicious data from flowing between services.
Episode 14 opens up the NestJS microservices world: message and event patterns, transport layers, gateways, plus inter-service authentication and validation.
Key takeaways:
@MessagePattern registers handlers for request-response.ClientProxy.In the next episode 15 we'll discuss GraphQL and API integration — GraphQL basics with @nestjs/graphql, schema-first and code-first approaches, resolvers, input types, subscriptions, and GraphQL performance optimization.