Welcome back to the NestJS Expert Series! ๐
In Part 4, we built scalable microservices with RabbitMQ.
Now, itโs time to take the next step โ integrating them with an API Gateway and service-to-service communication.
๐ Why Use an API Gateway?
When your app grows into multiple microservices (Auth, Users, Orders, Payments, etc.), clients shouldnโt need to know where each service lives.
Instead, the API Gateway acts as a single entry point โ handling:
Authentication
Routing requests to the right microservice
Response aggregation
Rate limiting, caching, logging
This is the same principle used by Netflix, Uber, and Amazon for their distributed architectures.
โ๏ธ Step 1 โ Setup a New API Gateway Project
Letโs create a separate NestJS project to act as the gateway:
nest new api-gateway
Then, install the microservice package:
npm i @nestjs/microservices
๐ Step 2 โ Connect the Gateway to Microservices
In your app.module.ts of the API Gateway:
import { Module } from '@nestjs/common';
import { ClientsModule, Transport } from '@nestjs/microservices';
import { GatewayController } from './gateway.controller';
@Module({
imports: [
ClientsModule.register([
{
name: 'AUTH_SERVICE',
transport: Transport.TCP,
options: { host: 'localhost', port: 3001 },
},
{
name: 'USER_SERVICE',
transport: Transport.TCP,
options: { host: 'localhost', port: 3002 },
},
]),
],
controllers: [GatewayController],
})
export class AppModule {}
This defines two microservice connections:
AUTH_SERVICE (for authentication)
USER_SERVICE (for user-related operations)
๐งฉ Step 3 โ Build the Gateway Controller
gateway.controller.ts:
import { Controller, Get, Inject, Post, Body } from '@nestjs/common';
import { ClientProxy } from '@nestjs/microservices';
@Controller('gateway')
export class GatewayController {
constructor(
@Inject('AUTH_SERVICE') private authClient: ClientProxy,
@Inject('USER_SERVICE') private userClient: ClientProxy,
) {}
@Post('login')
async login(@Body() credentials: any) {
return this.authClient.send({ cmd: 'login' }, credentials);
}
@Get('users')
async getUsers() {
return this.userClient.send({ cmd: 'get_users' }, {});
}
}
โ Here:
The gateway sends messages to different microservices via TCP transport.
Each microservice listens for specific message patterns and responds.
๐ง Step 4 โ Listening in the Microservice
Example from user-service:
import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';
@Controller()
export class UserController {
@MessagePattern({ cmd: 'get_users' })
getUsers() {
return [
{ id: 1, name: 'Yogesh' },
{ id: 2, name: 'Aditi' },
];
}
}
Now, when the gateway sends { cmd: 'get_users' }, this microservice responds with a list of users.
๐ง Step 5 โ Add Authentication Middleware
To protect routes at the gateway level:
import { Injectable, NestMiddleware } from '@nestjs/common';
import * as jwt from 'jsonwebtoken';
@Injectable()
export class AuthMiddleware implements NestMiddleware {
use(req: any, res: any, next: () => void) {
const token = req.headers['authorization']?.split(' ')[1];
if (!token) return res.status(401).json({ message: 'Unauthorized' });
try {
const decoded = jwt.verify(token, 'SECRET_KEY');
req.user = decoded;
next();
} catch {
return res.status(401).json({ message: 'Invalid token' });
}
}
}
This ensures centralized authentication โ one verification at the gateway before forwarding requests to microservices.
๐ก Step 6 โ Service Discovery (Optional)
For dynamic scaling, you can integrate Consul or Eureka to allow automatic service registration and discovery.
This prevents hardcoding service URLs and enables horizontal scaling easily.
๐งญ Summary
โ
Implemented a central API Gateway
โ
Connected multiple microservices using TCP transport
โ
Added authentication middleware
โ
Laid the foundation for distributed, secure communication
๐ฎ Coming Up Next (Part 6)
In Part 6, weโll take it even further:
๐ง โMonitoring, Logging, and Observability in NestJS Microservices.โ
Youโll learn how to use Winston, Prometheus, and Grafana to track, debug, and optimize microservice performance.
Top comments (0)