A NestJS module providing rate limiting features using the Bottleneck package.
npm install @zedquads/nestjs-bottleneckThis package provides a NestJS module and decorators to easily integrate the bottleneck rate-limiting library with your NestJS applications, supporting both REST and GraphQL.
First, install the package along with its peer dependencies:
``bash`
npm install @zedquads/nestjs-bottleneck bottleneck
optional:
`bash`
npm install ioredis redis
Module Setup
Register the BottleneckModule in your NestJS application.
Static Configuration:
`ts
import { Module } from '@nestjs/common';
import { BottleneckModule } from '@zedquads/nestjs-bottleneck';
@Module({
imports: [
BottleneckModule.forRoot({
maxConcurrent: 5,
minTime: 100,
datastore: 'ioredis',
connection: { host: 'localhost', port: 6379 },
isGlobal: true, // Set to 'false' to make the module local
}),
],
})
export class AppModule {}
`
Async Configuration:
`ts
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { BottleneckModule } from '@zedquads/nestjs-bottleneck';
@Module({
imports: [
ConfigModule.forRoot(),
BottleneckModule.forRootAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
maxConcurrent: configService.get
minTime: configService.get
datastore: 'ioredis',
connection: {
host: configService.get
port: configService.get
},
}),
inject: [ConfigService],
isGlobal: true, // Set to 'false' to make the module local
}),
],
})
export class AppModule {}
`
Use the @Bottleneck decorator to apply rate limiting to your methods. It can be used in both REST controllers and GraphQL resolvers.
REST Example:
`ts
import { Controller, Get, Query } from '@nestjs/common';
import { Bottleneck } from '@zedquads/nestjs-bottleneck';
@Controller('example')
export class ExampleController {
@Get()
@Bottleneck() // Default key: ExampleController:exampleMethod
async exampleMethod() {
return 'This method is rate limited by Bottleneck.';
}
@Get('custom')
@Bottleneck('custom-key') // Custom static key
async customKeyMethod() {
return 'This method is rate limited by Bottleneck with a custom key.';
}
@Get('mapped')
@Bottleneck((param) => mapped-key:${param}, {This method is rate limited by Bottleneck with a dynamic key: ${param}.
maxConcurrent: 3,
minTime: 200,
}) // Dynamic key and options
async mappedKeyMethod(@Query('param') param: string) {
return ;`
}
}
GraphQL Example:
`ts
import { Resolver, Query, Args } from '@nestjs/graphql';
import { Bottleneck } from '@zedquads/nestjs-bottleneck';
@Resolver()
export class ExampleResolver {
@Query(() => String)
@Bottleneck() // Default key: ExampleResolver:exampleMethod
async exampleMethod() {
return 'This method is rate limited by Bottleneck.';
}
@Query(() => String)
@Bottleneck('custom-key') // Custom static key
async customKeyMethod() {
return 'This method is rate limited by Bottleneck with a custom key.';
}
@Query(() => String)
@Bottleneck((param) => mapped-key:${param}, {This method is rate limited by Bottleneck with a dynamic key: ${param}.
maxConcurrent: 3,
minTime: 200,
}) // Dynamic key and options
async mappedKeyMethod(@Args('param') param: string) {
return ;`
}
}
Wrapping Functions
You can also use the Bottleneck service to wrap functions:
`ts
import { Injectable } from '@nestjs/common';
import { BottleneckService } from '@zedquads/nestjs-bottleneck';
@Injectable()
export class ExampleService {
constructor(private readonly bottleneckService: BottleneckService) {}
async wrapFunctionExample() {
const wrappedFunction = this.bottleneckService
.getGroupLimiter(
'example-group',
'example-key',
{ maxConcurrent: 3, minTime: 200 }, // Optional custom options
)
.wrap(async (param: string) => {
// Function logic here
return Processed: ${param};
});
return wrappedFunction('exampleParam');
}
}
`
Custom Decorator
Create custom decorators to use Bottleneck options:
`ts
import { Inject } from '@nestjs/common';
import { BOTTLENECK_OPTIONS } from '@zedquads/nestjs-bottleneck';
export const InjectBottleneckOptions = () => Inject(BOTTLENECK_OPTIONS);
``
Refer to the official Bottleneck documentation for more detailed configurations and options: Bottleneck on npm.