Rate Limiting in NestJS: A Complete Guide with Examples
Syed Ali Hamza Zaidi ?
Software Engineer | MERN | Web 3.0 | Nest JS | Next JS | React JS | React Native | Node JS | Postgres | MySQL | MongoDB | JavaScript | TypeScript | Material UI | Bootstrap 5 | Tailwind | CSS-3 | HTML-5
Rate limiting is a crucial technique to control the number of requests a client can make to your API within a specific time frame. It helps prevent abuse, ensures fair usage, and protects your server from being overwhelmed. NestJS provides a built-in @nestjs/throttler package to implement rate limiting easily.
In this article, we’ll cover the following topics in detail:
Let’s dive in!
1. Install the Required Package
To get started, you need to install the @nestjs/throttler package:
npm install @nestjs/throttler
This package provides the necessary tools to implement rate limiting in your NestJS application.
2. Controller with Custom Rate Limits
Once the package is installed, you can configure rate limiting globally and apply custom rate limits to specific routes.
Global Rate Limiting
First, configure the ThrottlerModule in your AppModule:
import { Module } from '@nestjs/common';
import { ThrottlerModule } from '@nestjs/throttler';
import { AppController } from './app.controller';
@Module({
imports: [
ThrottlerModule.forRoot({
throttlers: [
{
ttl: 60000, // Time-to-live in milliseconds (1 minute)
limit: 10, // Maximum number of requests within the TTL
},
],
}),
],
controllers: [AppController],
})
export class AppModule {}
Custom Rate Limits for Specific Routes
You can override the global rate limit for specific routes using the @Throttle() decorator:
import { Controller, Get } from '@nestjs/common';
import { Throttle } from '@nestjs/throttler';
@Controller()
export class AppController {
@Get('public')
@Throttle({ default: { ttl: 30000, limit: 5 } }) // 5 requests per 30 seconds
getPublicData() {
return 'This is public data.';
}
@Get('private')
getPrivateData() {
return 'This is private data.';
}
}
In this example:
3. Skipping Rate Limiting with @SkipThrottle
Sometimes, you may want to exclude certain routes or controllers from rate limiting. The @SkipThrottle decorator allows you to do this.
Skip a Specific Route
import { Controller, Get } from '@nestjs/common';
import { SkipThrottle } from '@nestjs/throttler';
@Controller()
export class AppController {
@Get('health')
@SkipThrottle() // Skip rate limiting for this route
checkHealth() {
return 'Service is healthy.';
}
}
Skip an Entire Controller
领英推荐
import { Controller, Get } from '@nestjs/common';
import { SkipThrottle } from '@nestjs/throttler';
@SkipThrottle() // Skip rate limiting for all routes in this controller
@Controller('status')
export class StatusController {
@Get()
getStatus() {
return 'Service is running.';
}
}
4. Using ThrottlerGuard with GraphQL
The ThrottlerGuard can also be used with GraphQL APIs. However, since GraphQL uses a different execution context, you need to customize the guard to extract the request and response objects.
Custom GqlThrottlerGuard
Create a custom guard for GraphQL:
import { ExecutionContext, Injectable } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';
import { ThrottlerGuard } from '@nestjs/throttler';
@Injectable()
export class GqlThrottlerGuard extends ThrottlerGuard {
getRequestResponse(context: ExecutionContext) {
const gqlContext = GqlExecutionContext.create(context); // Get GraphQL context
const ctx = gqlContext.getContext(); // Extract request and response
return { req: ctx.req, res: ctx.res };
}
}
Apply the Custom Guard
Update your AppModule to use the custom guard:
import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';
import { ThrottlerModule } from '@nestjs/throttler';
import { GqlThrottlerGuard } from './gql-throttler.guard';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { join } from 'path';
@Module({
imports: [
ThrottlerModule.forRoot({
throttlers: [
{
ttl: 60000, // 1 minute
limit: 10, // 10 requests per minute
},
],
}),
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
playground: true,
context: ({ req, res }) => ({ req, res }),
autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
}),
],
providers: [
{
provide: APP_GUARD,
useClass: GqlThrottlerGuard, // Apply the custom GraphQL guard
},
],
})
export class AppModule {}
5. Role-Based Rate Limiting
You can implement role-based rate limiting by extending the ThrottlerGuard and customizing the rate limits based on the user's role.
Custom RoleBasedThrottlerGuard
import { ExecutionContext, Injectable } from '@nestjs/common';
import { ThrottlerGuard } from '@nestjs/throttler';
@Injectable()
export class RoleBasedThrottlerGuard extends ThrottlerGuard {
protected async getRateLimit(context: ExecutionContext): Promise<number> {
const request = context.switchToHttp().getRequest();
const user = request.user; // Assuming user is attached to the request
// Apply different rate limits based on user role
if (user?.role === 'admin') {
return 100; // Admins get 100 requests per minute
} else if (user?.role === 'manager') {
return 50; // Manager users get 50 requests per minute
} else {
return 10; // Regular users get 10 requests per minute
}
}
}
Apply the Role-Based Guard
Update your AppModule to use the role-based guard:
import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';
import { ThrottlerModule } from '@nestjs/throttler';
import { RoleBasedThrottlerGuard } from './role-based-throttler.guard';
@Module({
imports: [
ThrottlerModule.forRoot({
throttlers: [
{
ttl: 60000, // 1 minute
limit: 10, // Default limit (overridden by RoleBasedThrottlerGuard)
},
],
}),
],
providers: [
{
provide: APP_GUARD,
useClass: RoleBasedThrottlerGuard, // Apply the role-based guard
},
],
})
export class AppModule {}
Conclusion
Rate limiting is a powerful tool to protect your API from abuse and ensure fair usage. With NestJS and the @nestjs/throttler package, you can easily implement global and custom rate limits, skip rate limiting for specific routes, use it with GraphQL, and even implement role-based rate limiting.
By following this guide, you can build a robust and secure API with NestJS. Let me know if you have further questions! ??
Check out the full implementation here: ?? GitHub Repository
?? Follow Me for More Content:
?? Happy Learning! ??
#NestJS #RateLimiting #API #WebDevelopment #Backend #NodeJS #GraphQL #RESTAPI #Coding #Developer