Home / blog / API Gateway with NestJS: Handle Multi-Service Routing, Authentication, and Rate Limiting
API Gateway with NestJS: Handle Multi-Service Routing, Authentication, and Rate Limiting

API Gateway with NestJS: Handle Multi-Service Routing, Authentication, and Rate Limiting

Featured

API Gateway with NestJS: Handle Multi-Service Routing, Authentication, and Rate Limiting

a

admin

Author

25 min read
288 Views
June 25, 2025

Learn how to build a powerful API Gateway using NestJS to route requests between microservices, apply authentication, and manage rate limiting. A practical, real-world guide for scalable microservice architecture.

📦 API Gateway with NestJS: Handle Multi-Service Routing, Auth, and Rate Limiting

Modern applications are no longer monolithic. They’re made up of microservices — small, independently deployed services that focus on specific business functions.

But when services grow, we need a single entry point to:

  • Route requests to the right service
  • Authenticate users
  • Apply rate limits and security rules
  • Aggregate responses

That’s where an API Gateway comes in.

In this hands-on guide, I’ll show you how to build a robust API Gateway with NestJS, using:

  • HTTP Proxying for routing
  • Guards for Authentication
  • Rate Limiting for abuse protection
  • Support for multiple microservices (HTTP & TCP)

Let’s build something awesome. 🚀

🧠 What is an API Gateway?

An API Gateway is a single layer between your frontend and multiple backend services. It accepts requests, validates them, and forwards them to the correct microservice.

🔁 Example Use Case

Frontend → API Gateway → Auth Service  
                        → Users Service  
                        → Orders Service

Instead of calling each service directly, the frontend only communicates with the gateway, simplifying architecture and allowing centralized control.

🏗️ Project Setup

Start by creating a new NestJS project for the gateway:

npx @nestjs/cli new api-gateway
cd api-gateway

Install the needed libraries:

npm install --save axios @nestjs/throttler

We’ll use:

  • axios for HTTP proxying
  • @nestjs/throttler for rate limiting

🗂️ Folder Structure (Simplified)

src/
├── main.ts
├── gateway.controller.ts
├── gateway.service.ts
├── auth.guard.ts
├── throttler.guard.ts
├── app.module.ts

🔀 1. Proxy Requests to Microservices

Let’s say we want to route:

  • /auth/login → Auth Service
  • /users/profile → Users Service

🧩 gateway.service.ts

import { Injectable } from '@nestjs/common';
import axios, { AxiosRequestConfig } from 'axios';

@Injectable()
export class GatewayService {
  private services = {
    auth: 'http://localhost:3001',
    users: 'http://localhost:3002',
  };

  async forward(service: 'auth' | 'users', path: string, method: string, body: any, headers: any) {
    const url = `${this.services[service]}${path}`;
    const config: AxiosRequestConfig = {
      method,
      url,
      headers,
      data: body,
    };
    const res = await axios(config);
    return res.data;
  }
}

🎮 2. Create a Gateway Controller

import {
  Controller,
  Req,
  Res,
  All,
  UseGuards,
  HttpException,
  HttpStatus,
} from '@nestjs/common';
import { Request, Response } from 'express';
import { GatewayService } from './gateway.service';
import { AuthGuard } from './auth.guard';
import { ThrottlerGuard } from './throttler.guard';

@Controller()
export class GatewayController {
  constructor(private gatewayService: GatewayService) {}

  @All('*')
  @UseGuards(ThrottlerGuard, AuthGuard)
  async proxy(@Req() req: Request, @Res() res: Response) {
    try {
      const [_, service, ...restPath] = req.path.split('/');
      const path = '/' + restPath.join('/');
      const data = await this.gatewayService.forward(
        service as 'auth' | 'users',
        path,
        req.method,
        req.body,
        req.headers,
      );
      res.json(data);
    } catch (error) {
      throw new HttpException(error?.response?.data || 'Service Error', HttpStatus.BAD_GATEWAY);
    }
  }
}

This intercepts all incoming requests (@All('*')) and dynamically proxies them to the appropriate service based on the path.

🔐 3. Add an Authentication Guard

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const req = context.switchToHttp().getRequest();
    const auth = req.headers['authorization'];
    // You could validate a token here, or forward it to the auth service
    return !!auth; // For demo purposes, allow if Authorization header exists
  }
}

In production, you'd verify JWT tokens or forward the token to the auth service to validate.

🧃 4. Apply Rate Limiting (Per IP)

import { Injectable } from '@nestjs/common';
import {
  ThrottlerGuard as BaseThrottlerGuard,
  ThrottlerModule,
} from '@nestjs/throttler';

@Injectable()
export class ThrottlerGuard extends BaseThrottlerGuard {}

In your app.module.ts:

import { Module } from '@nestjs/common';
import { ThrottlerModule } from '@nestjs/throttler';
import { GatewayController } from './gateway.controller';
import { GatewayService } from './gateway.service';
import { AuthGuard } from './auth.guard';
import { ThrottlerGuard } from './throttler.guard';

@Module({
  imports: [
    ThrottlerModule.forRoot({
      ttl: 60, // 1 minute
      limit: 10, // 10 requests per minute per IP
    }),
  ],
  controllers: [GatewayController],
  providers: [GatewayService, AuthGuard, ThrottlerGuard],
})
export class AppModule {}

🔌 5. Bonus: Support for TCP Microservices

If your microservices use TCP instead of HTTP, you can use NestJS’s ClientProxy.

But that’s a topic for another post 😉 (let me know if you want me to write that next!)

✅ Final Thoughts

An API Gateway is essential for any production-level microservices system.

By combining:

  • Dynamic routing
  • Centralized authentication
  • Rate limiting & security
  • Flexible microservice forwarding

…you gain full control, scalability, and flexibility across your backend.

NestJS makes it surprisingly clean and powerful to implement these ideas.

🔗 Bonus Resources

🙌 Was this helpful?

If you found this post useful, share it with someone building with microservices or NestJS.

share this post

Comments (0)

Leave a Comment

0/1000 characters
Loading comments...
Link Copied