### Example: Implementing ThrottlerOptionsFactory Source: https://github.com/nestjs/throttler/blob/master/_autodocs/types.md Example of a service implementing ThrottlerOptionsFactory to provide throttler options based on configuration service values. Ensure ThrottlerModule is imported. ```typescript import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { ThrottlerOptionsFactory, ThrottlerModuleOptions } from '@nestjs/throttler'; @Injectable() export class ConfigurableThrottlerService implements ThrottlerOptionsFactory { constructor(private configService: ConfigService) {} createThrottlerOptions(): ThrottlerModuleOptions { return [ { ttl: this.configService.get('THROTTLE_TTL'), limit: this.configService.get('THROTTLE_LIMIT'), }, ]; } } ``` -------------------------------- ### ThrottlerModuleOptions Example Source: https://github.com/nestjs/throttler/blob/master/_autodocs/types.md Example configuration for ThrottlerModuleOptions, demonstrating how to set rate limits and customize the error message using ThrottlerLimitDetail. ```typescript const options: ThrottlerModuleOptions = { throttlers: [{ limit: 10, ttl: 60000 }], errorMessage: (context, detail) => { return `Too many requests. Limit: ${detail.limit} per ${detail.ttl}ms. ` + `Blocked for ${detail.timeToBlockExpire}s.`; }, }; ``` -------------------------------- ### ThrottlerOptions Example Configuration Source: https://github.com/nestjs/throttler/blob/master/_autodocs/types.md An example demonstrating how to configure ThrottlerOptions. This configuration sets a limit of 100 requests per 60 seconds, with a 5-minute block duration, ignores bot user agents, and enables response headers. ```typescript const throttlerConfig: ThrottlerOptions = { name: 'api', limit: 100, ttl: 60000, blockDuration: 300000, ignoreUserAgents: [/bot/i, /crawler/i], skipIf: (context) => context.switchToHttp().getRequest().user?.isAdmin, setHeaders: true, }; ``` -------------------------------- ### Install NestJS Throttler Source: https://github.com/nestjs/throttler/blob/master/README.md Install the NestJS Throttler package using npm. ```bash npm i --save @nestjs/throttler ``` -------------------------------- ### Example: Injecting Throttler Storage Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/decorators.md Shows how to inject the ThrottlerStorage service and use its methods, such as 'increment', to interact with the rate-limiting data. This example demonstrates checking the status of a given key. ```typescript import { Injectable } from '@nestjs/common'; import { InjectThrottlerStorage, ThrottlerStorage } from '@nestjs/throttler'; @Injectable() export class StorageInspectionService { constructor( @InjectThrottlerStorage() private readonly storage: ThrottlerStorage, ) {} async checkStatus(key: string) { const record = await this.storage.increment(key, 60000, 10, 300000, 'default'); return record; } } ``` -------------------------------- ### Minimal Working Example of ThrottlerModule Source: https://github.com/nestjs/throttler/blob/master/_autodocs/00-START-HERE.md This example demonstrates the basic setup for the ThrottlerModule in your NestJS application. It configures a default rate limit of 10 requests per 60-second window and applies it globally using APP_GUARD. ```typescript import { Module } from '@nestjs/common'; import { ThrottlerModule, ThrottlerGuard, seconds } from '@nestjs/throttler'; import { APP_GUARD } from '@nestjs/core'; @Module({ imports: [ ThrottlerModule.forRoot([ { ttl: seconds(60), // 60 second window limit: 10, // 10 requests allowed }, ]), ], providers: [ { provide: APP_GUARD, useClass: ThrottlerGuard, }, ], }) export class AppModule {} ``` -------------------------------- ### Custom Storage Implementation Source: https://github.com/nestjs/throttler/blob/master/_autodocs/README.md Demonstrates how to implement a custom storage mechanism for the Throttler module, using Redis as an example. ```APIDOC ## Custom Storage Implement the `ThrottlerStorage` interface to persist rate limit data. ### `RedisThrottlerStorage` Example This example shows a custom storage implementation using Redis. ```typescript import { Injectable } from '@nestjs/common'; import { ThrottlerStorage, ThrottlerStorageRecord } from '@nestjs/throttler'; import Redis from 'ioredis'; @Injectable() export class RedisThrottlerStorage implements ThrottlerStorage { constructor(private redis: Redis) {} async increment( key: string, ttl: number, limit: number, blockDuration: number, throttlerName: string, ): Promise { const redisKey = `throttle:${key}:${throttlerName}`; const hits = await this.redis.incr(redisKey); if (hits === 1) { await this.redis.pexpire(redisKey, ttl); } const ttl_remaining = await this.redis.pttl(redisKey); const isBlocked = hits > limit; return { totalHits: hits, timeToExpire: Math.ceil(ttl_remaining / 1000), isBlocked, timeToBlockExpire: isBlocked ? Math.ceil(blockDuration / 1000) : 0, }; } } ``` ### `ThrottlerStorage` Interface - **`increment(key: string, ttl: number, limit: number, blockDuration: number, throttlerName: string): Promise`**: Increments the hit count for a given key and returns the current record. ### `ThrottlerStorageRecord` Structure - **`totalHits`** (number): The total number of hits recorded. - **`timeToExpire`** (number): The remaining time in seconds until the rate limit expires. - **`isBlocked`** (boolean): Indicates if the client is currently blocked due to exceeding the limit. - **`timeToBlockExpire`** (number): The remaining time in seconds until the block expires (if `isBlocked` is true). ``` -------------------------------- ### Custom Throttler Key Generation Example Source: https://github.com/nestjs/throttler/blob/master/_autodocs/types.md An example of a custom key generation function that includes the HTTP method and request path for more granular throttling. This function is passed to ThrottlerModule.forRoot. ```typescript import { sha256 } from '@nestjs/throttler'; const generateKey: ThrottlerGenerateKeyFunction = (context, tracker, name) => { const req = context.switchToHttp().getRequest(); const prefix = `${req.method}-${req.path}-${name}`; return sha256(`${prefix}-${tracker}`); }; ThrottlerModule.forRoot({ throttlers: [{ limit: 10, ttl: 60000 }], generateKey, }) ``` -------------------------------- ### Example: Injecting ThrottlerStorage Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/providers.md Illustrates how to inject the ThrottlerStorage instance into a service using the `@InjectThrottlerStorage()` decorator. ```typescript import { Injectable } from '@nestjs/common'; import { InjectThrottlerStorage, ThrottlerStorage } from '@nestjs/throttler'; @Injectable() export class RateLimitMonitor { constructor( @InjectThrottlerStorage() private storage: ThrottlerStorage, ) {} async getStatus(key: string) { return await this.storage.increment(key, 60000, 10, 300000, 'default'); } } ``` -------------------------------- ### Example: Default Storage Usage Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/providers.md Shows how to configure the ThrottlerModule to use the default storage service by not providing a custom storage option. ```typescript import { ThrottlerModule } from '@nestjs/throttler'; import { Module } from '@nestjs/common'; @Module({ imports: [ ThrottlerModule.forRoot([ { limit: 10, ttl: 60000 }, ]), ], }) export class AppModule {} ``` -------------------------------- ### Response Headers and Example Source: https://github.com/nestjs/throttler/blob/master/_autodocs/errors.md Details the HTTP response headers returned when a rate limit is exceeded and provides an example of the JSON response body. ```APIDOC ### Response Headers When throttled, the response includes: - **HTTP Status:** `429 Too Many Requests` - **Retry-After:** Seconds until client is unblocked (integer) - **Content-Type:** `application/json` (default NestJS HTTP exception format) **Example Response** ```json { "statusCode": 429, "message": "ThrottlerException: Too Many Requests", "error": "Too Many Requests" } ``` ``` -------------------------------- ### Example: Custom Storage Implementation Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/providers.md Demonstrates how to provide a custom storage class to the ThrottlerModule. Ensure your custom class implements the ThrottlerStorage interface. ```typescript import { ThrottlerModule, ThrottlerStorage } from '@nestjs/throttler'; import { Module } from '@nestjs/common'; class CustomStorage implements ThrottlerStorage { async increment(...) { // Custom implementation } } @Module({ imports: [ ThrottlerModule.forRoot({ storage: new CustomStorage(), throttlers: [ { limit: 10, ttl: 60000 }, ], }), ], }) export class AppModule {} ``` -------------------------------- ### Custom Tracker Function Example Source: https://github.com/nestjs/throttler/blob/master/_autodocs/types.md Provides an example of implementing a ThrottlerGetTrackerFunction to identify clients based on user ID or IP address. ```typescript const getTracker: ThrottlerGetTrackerFunction = async (req, context) => { const user = context.switchToHttp().getRequest().user; return user?.id || req.ip; }; ThrottlerModule.forRoot({ throttlers: [{ limit: 10, ttl: 60000 }], getTracker, }) ``` -------------------------------- ### Applying ThrottlerGuard to a Controller Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/throttler-guard.md This example shows how to apply the ThrottlerGuard globally to a controller, enabling rate limiting for all its routes. ```typescript import { Controller, Get, UseGuards } from '@nestjs/common'; import { ThrottlerGuard } from '@nestjs/throttler'; @Controller('api') @UseGuards(ThrottlerGuard) export class ApiController { @Get('data') getData() { return { message: 'Rate limited data' }; } } ``` -------------------------------- ### Resolvable Type Usage Examples Source: https://github.com/nestjs/throttler/blob/master/_autodocs/types.md Illustrates how to use the Resolvable type with static values, synchronous functions, and asynchronous functions for configuration. ```typescript limit: 10 ``` ```typescript limit: (ctx) => isPremium(ctx) ? 100 : 10 ``` ```typescript limit: (ctx) => fetchUserLimit(ctx) ``` -------------------------------- ### Example: Injecting Throttler Options Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/decorators.md Demonstrates how to inject and use the ThrottlerModuleOptions within a custom service. Ensure the ThrottlerModule is imported and configured in your application. ```typescript import { Injectable } from '@nestjs/common'; import { InjectThrottlerOptions } from '@nestjs/throttler'; import { ThrottlerModuleOptions } from '@nestjs/throttler'; @Injectable() export class CustomThrottlerService { constructor( @InjectThrottlerOptions() private readonly options: ThrottlerModuleOptions, ) {} getOptions() { return this.options; } } ``` -------------------------------- ### Basic Throttler Setup in AppModule Source: https://github.com/nestjs/throttler/blob/master/_autodocs/README.md Configure the ThrottlerModule globally in your AppModule to apply rate limiting across your application. This setup defines a default limit of 10 requests per 60 seconds. ```typescript import { Module } from '@nestjs/common'; import { ThrottlerModule, seconds } from '@nestjs/throttler'; import { APP_GUARD } from '@nestjs/core'; @Module({ imports: [ ThrottlerModule.forRoot([ { ttl: seconds(60), limit: 10, }, ]), ], providers: [ { provide: APP_GUARD, useClass: ThrottlerGuard, }, ], }) export class AppModule {} ``` -------------------------------- ### Example: ThrottlerModule Async Registration with useFactory Source: https://github.com/nestjs/throttler/blob/master/_autodocs/types.md Demonstrates asynchronous registration of the ThrottlerModule using the 'useFactory' option. This approach is useful for providing options dynamically based on injected services like ConfigService. ```typescript ThrottlerModule.forRootAsync({ imports: [ConfigModule], inject: [ConfigService], useFactory: (config: ConfigService) => [{ ttl: config.get('THROTTLE_TTL'), limit: config.get('THROTTLE_LIMIT'), }], }) ``` -------------------------------- ### Custom RedisThrottlerStorage Implementation Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/throttler-storage-service.md Example of implementing a custom ThrottlerStorage provider using Redis. This demonstrates how to override the increment method for custom storage logic. ```typescript import { ThrottlerStorage } from '@nestjs/throttler'; class RedisThrottlerStorage implements ThrottlerStorage { async increment( key: string, ttl: number, limit: number, blockDuration: number, throttlerName: string, ): Promise { // Custom implementation } } @Module({ imports: [ ThrottlerModule.forRoot([ { ttl: 60000, limit: 10, storage: new RedisThrottlerStorage(), }, ]), ], }) export class AppModule {} ``` -------------------------------- ### Example JSON Response for Throttled Request Source: https://github.com/nestjs/throttler/blob/master/_autodocs/errors.md Illustrates the JSON structure of an HTTP response when a client exceeds the rate limit. ```json { "statusCode": 429, "message": "ThrottlerException: Too Many Requests", "error": "Too Many Requests" } ``` -------------------------------- ### Manual Provider Creation for Throttler Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/providers.md Example of manually creating Throttler providers, including options and storage, within a NestJS module. ```typescript import { Module, Provider } from '@nestjs/common'; import { createThrottlerProviders, ThrottlerStorageProvider } from '@nestjs/throttler'; @Module({ providers: [ ...createThrottlerProviders([{ limit: 10, ttl: 60000 }]), ThrottlerStorageProvider, ], exports: [ ...createThrottlerProviders([{ limit: 10, ttl: 60000 }]), ThrottlerStorageProvider, ], }) export class CustomThrottlerModule {} ``` -------------------------------- ### Custom Exception Handler Source: https://github.com/nestjs/throttler/blob/master/_autodocs/errors.md Provides an example of creating a custom ExceptionFilter to format the throttler exception response, and how to register it globally or within a module. ```APIDOC ### Custom Exception Handler Create a filter to format throttler exceptions: ```typescript import { ThrottlerException } from '@nestjs/throttler'; import { Catch, ExceptionFilter, ArgumentsHost, HttpStatus } from '@nestjs/common'; import { Response } from 'express'; @Catch(ThrottlerException) export class ThrottlerExceptionFilter implements ExceptionFilter { catch(exception: ThrottlerException, host: ArgumentsHost) { const response = host.switchToHttp().getResponse(); response.status(HttpStatus.TOO_MANY_REQUESTS).json({ success: false, error: { code: 'RATE_LIMIT_EXCEEDED', message: 'Too many requests. Please try again later.', }, }); } } // Register in module @Module({ providers: [ThrottlerExceptionFilter], }) export class AppModule {} // Or globally import { APP_FILTER } from '@nestjs/core'; @Module({ providers: [ { provide: APP_FILTER, useClass: ThrottlerExceptionFilter, }, ], }) export class AppModule {} ``` ``` -------------------------------- ### Inject Throttler Options in Custom Service Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/utility-functions.md Example demonstrating how to inject ThrottlerModuleOptions using the getOptionsToken utility in a custom NestJS service. ```typescript import { getOptionsToken, ThrottlerModuleOptions } from '@nestjs/throttler'; import { Inject, Injectable } from '@nestjs/common'; @Injectable() export class CustomService { constructor( @Inject(getOptionsToken()) private options: ThrottlerModuleOptions, ) {} getConfig() { return this.options; } } ``` -------------------------------- ### Custom ThrottlerGuard to Skip Throttling for Admins Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/throttler-guard.md Example of extending ThrottlerGuard to skip throttling for requests where the user's role is 'admin'. ```typescript import { ThrottlerGuard } from '@nestjs/throttler'; import { Injectable } from '@nestjs/common'; import { ExecutionContext } from '@nestjs/common'; @Injectable() export class CustomThrottlerGuard extends ThrottlerGuard { protected async shouldSkip(context: ExecutionContext): Promise { const request = context.switchToHttp().getRequest(); return request.user?.role === 'admin'; } } ``` -------------------------------- ### Inject Throttler Storage in Custom Service Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/utility-functions.md Example demonstrating how to inject ThrottlerStorage using the getStorageToken utility in a custom NestJS service to interact with storage. ```typescript import { getStorageToken, ThrottlerStorage } from '@nestjs/throttler'; import { Inject, Injectable } from '@nestjs/common'; @Injectable() export class StorageInspectionService { constructor( @Inject(getStorageToken()) private storage: ThrottlerStorage, ) {} async checkKey(key: string) { const record = await this.storage.increment(key, 60000, 10, 300000, 'default'); return record; } } ``` -------------------------------- ### Custom ThrottlerGuard for Key Generation with Path Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/throttler-guard.md Example of overriding generateKey in ThrottlerGuard to include the HTTP method and path in the generated SHA256 hash for the storage key. ```typescript @Injectable() export class CustomKeyGuard extends ThrottlerGuard { protected generateKey( context: ExecutionContext, suffix: string, name: string, ): string { const request = context.switchToHttp().getRequest(); const prefix = `${request.method}-${request.path}-${name}`; return sha256(`${prefix}-${suffix}`); } } ``` -------------------------------- ### Reset Skip in a Skip-All Class Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/decorators.md Demonstrates how to re-enable throttling for specific routes within a controller that has @SkipThrottle({ default: true }) applied at the class level. This example shows re-enabling with default limits and custom limits. ```typescript import { Controller, Get, } from '@nestjs/common'; import { SkipThrottle, Throttle, seconds } from '@nestjs/throttler'; @Controller('mixed') @SkipThrottle({ default: true }) export class MixedController { @Get('fast') // Skips throttling fast() { return { data: 'fast' }; } @Get('slow') @SkipThrottle({ default: false }) // Re-enables throttling slow() { return { data: 'rate limited' }; } @Get('custom') @Throttle({ default: { limit: 100, ttl: seconds(60) } }) // Also re-enables with custom limits custom() { return { data: 'custom limited' }; } } ``` -------------------------------- ### Custom ThrottlerStorage Implementation Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/throttler-storage-service.md Demonstrates how to implement a custom storage provider by extending the ThrottlerStorage abstract class and providing a custom implementation for the increment method. ```APIDOC ## Custom ThrottlerStorage Implementation ### Description Provides a way to use custom storage for the Throttler module, such as RedisThrottlerStorage. ### Method Signature ```typescript increment( key: string, ttl: number, limit: number, blockDuration: number, throttlerName: string, ): Promise ``` ### Parameters - **key** (string) - The unique key for the rate limit. - **ttl** (number) - The time-to-live for the rate limit window in milliseconds. - **limit** (number) - The maximum number of requests allowed within the TTL. - **blockDuration** (number) - The duration in milliseconds for which the client will be blocked after exceeding the limit. - **throttlerName** (string) - The name of the throttler instance. ### Request Example ```typescript import { ThrottlerStorage } from '@nestjs/throttler'; class RedisThrottlerStorage implements ThrottlerStorage { async increment( key: string, ttl: number, limit: number, blockDuration: number, throttlerName: string, ): Promise { // Custom implementation } } ``` ### Response #### Success Response - **ThrottlerStorageRecord** (object) - A record containing the current hit count and expiration time. ``` -------------------------------- ### Async Options Provider for useClass or useExisting Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/providers.md This configuration is used for asynchronous options registration when using `useClass` or `useExisting`. It sets up the options provider and the class provider itself. ```typescript [ { provide: THROTTLER_OPTIONS, useFactory: (factory: ThrottlerOptionsFactory) => factory.createThrottlerOptions(), inject: [options.useExisting || options.useClass], }, { provide: options.useClass, useClass: options.useClass, }, ] ``` -------------------------------- ### Catching ThrottlerException Source: https://github.com/nestjs/throttler/blob/master/_autodocs/errors.md An example of how to create an ExceptionFilter in NestJS to catch and handle ThrottlerException, providing a custom response format. ```APIDOC ## Example: Catching ThrottlerException ```typescript import { ThrottlerException } from '@nestjs/throttler'; import { Catch, ExceptionFilter, HttpException } from '@nestjs/common'; @Catch(ThrottlerException) export class ThrottlerExceptionFilter implements ExceptionFilter { catch(exception: ThrottlerException, host: ArgumentsHost) { const response = host.switchToHttp().getResponse(); const status = exception.getStatus(); response.status(status).json({ statusCode: status, message: exception.message, error: 'Too Many Requests', }); } } ``` ``` -------------------------------- ### Troubleshoot Response Headers Not Set Source: https://github.com/nestjs/throttler/blob/master/_autodocs/INDEX.md Ensure response headers are included by setting `setHeaders: true` if they are currently missing. ```markdown Headers not in response | `setHeaders: false` | Set `setHeaders: true` ``` -------------------------------- ### Configure ThrottlerModule - With Options Source: https://github.com/nestjs/throttler/blob/master/_autodocs/INDEX.md Configure the ThrottlerModule with advanced options using `ThrottlerModule.forRoot()`. This allows specifying custom throttlers, storage, error messages, and a tracker function. ```typescript ThrottlerModule.forRoot({ throttlers: [{ ttl: 60000, limit: 10 }], storage: customStorage, errorMessage: 'Too many requests', getTracker: (req) => req.ip, }) ``` -------------------------------- ### Troubleshoot Throttler Not Working Source: https://github.com/nestjs/throttler/blob/master/_autodocs/INDEX.md Resolve issues where rate limiting is not functioning as expected by ensuring the guard is correctly registered. ```markdown Rate limiting not working | Guard not registered | Register via `APP_GUARD` or `@UseGuards()` ``` -------------------------------- ### ThrottlerModule Source: https://github.com/nestjs/throttler/blob/master/_autodocs/GENERATION-SUMMARY.txt Provides static methods forRoot() and forRootAsync() to configure the ThrottlerModule. ```APIDOC ## ThrottlerModule ### Description Configures the Throttler module for rate limiting. ### Static Methods #### `forRoot(options?: ThrottlerModuleOptions): DynamicModule` **Description**: Configures the module with synchronous options. **Parameters**: - **options** (ThrottlerModuleOptions) - Optional configuration object. **Returns**: - `DynamicModule` - The configured module. ### `forRootAsync(options: ThrottlerAsyncOptions): DynamicModule` **Description**: Configures the module with asynchronous options. **Parameters**: - **options** (ThrottlerAsyncOptions) - Asynchronous configuration object. **Returns**: - `DynamicModule` - The configured module. ``` -------------------------------- ### Catch ThrottlerException with Basic Response Source: https://github.com/nestjs/throttler/blob/master/_autodocs/errors.md An example of an ExceptionFilter that catches ThrottlerException and sends a JSON response with status code, message, and error type. ```typescript import { ThrottlerException } from '@nestjs/throttler'; import { Catch, ExceptionFilter, HttpException } from '@nestjs/common'; @Catch(ThrottlerException) export class ThrottlerExceptionFilter implements ExceptionFilter { catch(exception: ThrottlerException, host: ArgumentsHost) { const response = host.switchToHttp().getResponse(); const status = exception.getStatus(); response.status(status).json({ statusCode: status, message: exception.message, error: 'Too Many Requests', }); } } ``` -------------------------------- ### Async Configuration with UseClass Source: https://github.com/nestjs/throttler/blob/master/README.md Configure throttler options asynchronously using useClass, which requires a service that implements the ThrottlerOptionsFactory interface. ```typescript import { Module } from '@nestjs/common'; import { ThrottlerModule } from '@nestjs/throttler'; @Module({ imports: [ ThrottlerModule.forRootAsync({ imports: [ConfigModule], useClass: ThrottlerConfigService, }), ], }) export class AppModule {} ``` -------------------------------- ### Global Options and Custom Storage Configuration Source: https://github.com/nestjs/throttler/blob/master/_autodocs/configuration.md Configure global options like custom storage, ignored user agents, a custom tracker function, and an error message, alongside specific throttler settings. ```typescript import { Module } from '@nestjs/common'; import { ThrottlerModule, seconds } from '@nestjs/throttler'; import { RedisThrottlerStorage } from 'custom-storage'; @Module({ imports: [ ThrottlerModule.forRoot({ storage: new RedisThrottlerStorage(), ignoreUserAgents: [/bot/i, /crawler/i], getTracker: (req, context) => { const user = context.switchToHttp().getRequest().user; return user?.id || req.ip; }, errorMessage: (context, detail) => `Too many requests. Please retry after ${detail.timeToBlockExpire} seconds.`, throttlers: [ { name: 'api', ttl: seconds(60), limit: 100, }, ], }), ], }) export class AppModule {} ``` -------------------------------- ### Get Throttler Storage Token Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/utility-functions.md Returns the injection token for throttler storage. Useful for manual provider creation or accessing storage in custom providers. ```typescript export const getStorageToken = () => ThrottlerStorage ``` -------------------------------- ### Utility Functions Source: https://github.com/nestjs/throttler/blob/master/_autodocs/GENERATION-SUMMARY.txt Helper functions for time conversion and dependency injection tokens. ```APIDOC ## Utility Functions ### Time Converters - **`seconds(value: number): number`**: Converts a number to seconds. - **`minutes(value: number): number`**: Converts a number to minutes. - **`hours(value: number): number`**: Converts a number to hours. - **`days(value: number): number`**: Converts a number to days. - **`weeks(value: number): number`**: Converts a number to weeks. ### DI Tokens - **`getOptionsToken(): string`**: Returns the DI token for Throttler options. - **`getStorageToken(): string`**: Returns the DI token for Throttler storage service. ### Hashing Utility - **`sha256(data: string): string`**: Computes the SHA-256 hash of the input string. ``` -------------------------------- ### Get Throttler Options Token Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/utility-functions.md Returns the injection token for throttler options. Useful for manual provider creation or accessing options in custom providers. ```typescript export const getOptionsToken = () => THROTTLER_OPTIONS ``` -------------------------------- ### Synchronous Provider Registration (forRoot) Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/providers.md Use `forRoot` for synchronous registration of Throttler module providers. This method creates options and storage providers and returns a dynamic module. ```typescript static forRoot(options: ThrottlerModuleOptions = []): DynamicModule { const providers = [ ...createThrottlerProviders(options), ThrottlerStorageProvider ]; return { module: ThrottlerModule, providers, exports: providers, }; } ``` -------------------------------- ### Authentication Endpoint Rate Limiting Source: https://github.com/nestjs/throttler/blob/master/_autodocs/README.md Limit the number of login attempts to prevent brute-force attacks. This example restricts users to 5 login attempts per 15 minutes. ```typescript @Post('login') @Throttle({ default: { limit: 5, ttl: seconds(900) } }) async login(@Body() credentials: LoginDto) { // Limit login attempts to 5 per 15 minutes } ``` -------------------------------- ### Configure Custom Storage Backend Source: https://github.com/nestjs/throttler/blob/master/_autodocs/configuration.md Specifies a custom storage backend for rate-limit tracking, such as Redis. Defaults to an in-memory service if not provided. ```typescript storage: new RedisThrottlerStorage() ``` -------------------------------- ### Public API Endpoint Rate Limiting Source: https://github.com/nestjs/throttler/blob/master/_autodocs/README.md Apply rate limiting to a public API endpoint to control access frequency. This example limits requests to 100 per hour. ```typescript @Get('public-data') @Throttle({ default: { limit: 100, ttl: seconds(3600) } }) publicData() { return { data: 'public' }; } ``` -------------------------------- ### Troubleshoot All Requests Blocked Source: https://github.com/nestjs/throttler/blob/master/_autodocs/INDEX.md Fix the issue of all requests being blocked by increasing the `limit` value in the throttler configuration. ```markdown All requests blocked | Limit too low | Increase `limit` value ``` -------------------------------- ### onModuleInit Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/throttler-guard.md Initializes the guard when the module boots. Sorts throttlers by TTL and sets up common options. Called automatically by NestJS. ```APIDOC ## onModuleInit Initializes the guard when the module boots. Sorts throttlers by TTL and sets up common options. ```typescript async onModuleInit(): void ``` **Called automatically by NestJS** ``` -------------------------------- ### Custom ThrottlerGuard for Header-Based Tracker Identification Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/throttler-guard.md Example of extending ThrottlerGuard to use a custom header 'x-user-id' for tracking requests, falling back to IP address if the header is not present. ```typescript @Injectable() export class CustomTrackerGuard extends ThrottlerGuard { protected async getTracker(req: Record): Promise { const userId = req.headers['x-user-id']; return userId || req.ip; } } ``` -------------------------------- ### Troubleshoot Custom Tracker Not Used Source: https://github.com/nestjs/throttler/blob/master/_autodocs/INDEX.md Verify that the custom tracker is correctly configured in the module settings if it's not being utilized. ```markdown Custom tracker not used | Not in config | Add `getTracker` to module config ``` -------------------------------- ### Skip Default Throttler in Controller Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/decorators.md Use @SkipThrottle() on a route to disable rate limiting for that specific endpoint. This example shows disabling it for a 'health' route while 'data' remains rate-limited. ```typescript import { Controller, Get, } from '@nestjs/common'; import { SkipThrottle } from '@nestjs/throttler'; @Controller('public') export class PublicController { @Get('health') @SkipThrottle() healthCheck() { return { status: 'ok' }; } @Get('data') getData() { return { data: 'rate-limited' }; } } ``` -------------------------------- ### generateKey Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/throttler-guard.md Creates a hashed storage key from context, tracker, and throttler name. Returns a SHA256 hash of the formatted key. Defaults to combining class name, method name, throttler name, and suffix into a SHA256 hash. ```APIDOC ## generateKey Creates a hashed storage key from context, tracker, and throttler name. ```typescript protected generateKey(context: ExecutionContext, suffix: string, name: string): string ``` **Parameters** | Parameter | Type | Description | |-----------|------|-------------| | context | `ExecutionContext` | NestJS execution context | | suffix | `string` | Tracker identifier (IP, user ID, etc.) | | name | `string` | Throttler name from configuration | **Returns** `string` — SHA256 hash of formatted key **Default** — Combines class name, method name, throttler name, and suffix into SHA256 hash **Example: Custom key generation with path** ```typescript @Injectable() export class CustomKeyGuard extends ThrottlerGuard { protected generateKey( context: ExecutionContext, suffix: string, name: string, ): string { const request = context.switchToHttp().getRequest(); const prefix = `${request.method}-${request.path}-${name}`; return sha256(`${prefix}-${suffix}`); } } ``` ``` -------------------------------- ### ThrottlerModule Registration Source: https://github.com/nestjs/throttler/blob/master/_autodocs/INDEX.md Demonstrates how to register the ThrottlerModule using `forRoot` or `forRootAsync` options. ```typescript ThrottlerModule └─ forRoot(options) └─ forRootAsync(options) ``` -------------------------------- ### Skip Specific Named Throttlers Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/decorators.md Apply @SkipThrottle() with specific throttler names to selectively disable rate limiting. This example skips 'short' and 'medium' throttlers, but the 'long' throttler remains active. ```typescript import { Controller, Get, } from '@nestjs/common'; import { SkipThrottle } from '@nestjs/throttler'; @Controller('api') export class ApiController { @Get('public') @SkipThrottle({ short: true, medium: true }) // Still throttled by 'long' limiter publicEndpoint() { return { data: 'partially limited' }; } } ``` -------------------------------- ### Custom Redis Throttler Storage Implementation Source: https://github.com/nestjs/throttler/blob/master/_autodocs/configuration.md Implement the ThrottlerStorage interface to use a custom backend, such as Redis, for storing throttling records. This example shows how to increment hits and set expiration times in Redis. ```typescript import { Injectable } from '@nestjs/common'; import { ThrottlerStorage, ThrottlerStorageRecord } from '@nestjs/throttler'; import Redis from 'ioredis'; @Injectable() export class RedisThrottlerStorage implements ThrottlerStorage { constructor(private redis: Redis) {} async increment( key: string, ttl: number, limit: number, blockDuration: number, throttlerName: string, ): Promise { const redisKey = `throttle:${key}:${throttlerName}`; const hits = await this.redis.incr(redisKey); if (hits === 1) { await this.redis.pexpire(redisKey, ttl); } const timeToExpire = await this.redis.pttl(redisKey); const isBlocked = hits > limit; return { totalHits: hits, timeToExpire: Math.ceil(timeToExpire / 1000), isBlocked, timeToBlockExpire: isBlocked ? Math.ceil(blockDuration / 1000) : 0, }; } } // Use in module ThrottlerModule.forRoot({ storage: new RedisThrottlerStorage(), throttlers: [{ limit: 10, ttl: 60000 }], }) ``` -------------------------------- ### ThrottlerGuard Constructor Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/throttler-guard.md Initializes the ThrottlerGuard with configuration options, a storage service, and NestJS reflector. ```APIDOC ## Constructor ```typescript constructor( @InjectThrottlerOptions() protected readonly options: ThrottlerModuleOptions, @InjectThrottlerStorage() protected readonly storageService: ThrottlerStorage, protected readonly reflector: Reflector, ) ``` **Parameters** | Parameter | Type | Description | |-----------|------|-------------| | options | `ThrottlerModuleOptions` | Injected throttle configuration from ThrottlerModule | | storageService | `ThrottlerStorage` | Storage backend for tracking requests | | reflector | `Reflector` | NestJS reflector for reading metadata | ``` -------------------------------- ### Configure ThrottlerModule with Global Options Source: https://github.com/nestjs/throttler/blob/master/README.md Configure the ThrottlerModule with global time-to-live (ttl) and limit options using forRoot(). ```typescript @@filename(app.module) @Module({ imports: [ ThrottlerModule.forRoot([{ ttl: 60000, limit: 10, }]), ], }) export class AppModule {} ``` -------------------------------- ### Override Rate Limits per Route Source: https://github.com/nestjs/throttler/blob/master/_autodocs/00-START-HERE.md Use the @Throttle() decorator to define specific rate limits for individual routes, overriding the global configuration. This example sets a limit of 5 requests per 60 seconds for the 'data' endpoint. ```typescript @Throttle({ default: { limit: 5, ttl: seconds(60) } }) @Get('data') getData() { } ``` -------------------------------- ### ThrottlerModule.forRoot Signature Source: https://github.com/nestjs/throttler/blob/master/_autodocs/INDEX.md Use `forRoot` to configure the ThrottlerModule with synchronous options. It returns a `DynamicModule`. ```typescript static forRoot(options: ThrottlerModuleOptions = []): DynamicModule ``` -------------------------------- ### GraphQLModule Context Configuration (Apollo Fastify/Mercurius) Source: https://github.com/nestjs/throttler/blob/master/README.md Configure the GraphQLModule context for Apollo Server on Fastify or Mercurius to use request and reply objects, ensuring compatibility with the GqlThrottlerGuard. ```typescript GraphQLModule.forRoot({ // ... other GraphQL module options context: (request, reply) => ({ request, reply }), }); ``` -------------------------------- ### Identify Clients for Throttling Source: https://github.com/nestjs/throttler/blob/master/_autodocs/INDEX.md Explore different strategies for identifying clients to apply rate limits, including using IP addresses, user IDs, API keys, or composite keys. ```markdown Use IP address? ├─ Default → req.ip from getTracker() Use User ID? ├─ Override getTracker() to return user.id Use API Key? ├─ Override getTracker() to extract from header Use multiple identifiers? ├─ Create composite key in getTracker() ``` -------------------------------- ### Configure Throttler Dynamically Source: https://github.com/nestjs/throttler/blob/master/_autodocs/README.md Use dynamic configuration with `forRootAsync` to set up the throttler, allowing you to inject services like `ConfigService` to retrieve rate-limiting parameters. ```typescript ThrottlerModule.forRootAsync({ imports: [ConfigModule], inject: [ConfigService], useFactory: (config: ConfigService) => [ { ttl: config.get('THROTTLE_TTL'), limit: config.get('THROTTLE_LIMIT'), } ], }) ``` -------------------------------- ### Configure ThrottlerModule - Async Source: https://github.com/nestjs/throttler/blob/master/_autodocs/INDEX.md Configure the ThrottlerModule asynchronously using `ThrottlerModule.forRootAsync()`. This is useful for loading configuration from external sources like a ConfigModule. ```typescript ThrottlerModule.forRootAsync({ imports: [ConfigModule], inject: [ConfigService], useFactory: (config) => [{ ttl: config.get('TTL'), limit: config.get('LIMIT') }] }) ``` -------------------------------- ### Utility Functions Source: https://github.com/nestjs/throttler/blob/master/_autodocs/GENERATION-SUMMARY.txt Documentation for helper functions used within the Throttler module. ```APIDOC ## Utility Functions ### Description Helper functions for time conversions and other utilities. ### Functions - `timeConverter(time: number, unit: string): number`: Converts time to a specified unit. Refer to `utility-functions.md` for a complete list and details. ``` -------------------------------- ### Basic Single Throttler Configuration Source: https://github.com/nestjs/throttler/blob/master/_autodocs/configuration.md Configure a single throttler with a specified TTL and limit. This is the simplest way to enable rate limiting. ```typescript import { Module } from '@nestjs/common'; import { ThrottlerModule, seconds } from '@nestjs/throttler'; @Module({ imports: [ ThrottlerModule.forRoot([ { ttl: seconds(60), limit: 10, }, ]), ], }) export class AppModule {} ``` -------------------------------- ### Synchronous ThrottlerModule Configuration Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/throttler-module.md Use `forRoot` to synchronously register the ThrottlerModule with rate-limiting configurations. This method accepts an array of throttler configurations. ```typescript import { ThrottlerModule, seconds } from '@nestjs/throttler'; import { Module } from '@nestjs/common'; @Module({ imports: [ ThrottlerModule.forRoot([ { ttl: seconds(60), limit: 10, }, ]), ], }) export class AppModule {} ``` -------------------------------- ### ThrottlerModule Configuration Source: https://github.com/nestjs/throttler/blob/master/_autodocs/INDEX.md Configure the ThrottlerModule using `forRoot` or `forRootAsync` methods. You can provide simple configurations or more advanced options including custom storage and error messages. ```APIDOC ## ThrottlerModule Configuration ### Description Configures the ThrottlerModule with various options. ### Simple Configuration ```typescript ThrottlerModule.forRoot([ { ttl: 60000, limit: 10 } ]) ``` ### With Options ```typescript ThrottlerModule.forRoot({ throttlers: [{ ttl: 60000, limit: 10 }], storage: customStorage, errorMessage: 'Too many requests', getTracker: (req) => req.ip, }) ``` ### Async Configuration ```typescript ThrottlerModule.forRootAsync({ imports: [ConfigModule], inject: [ConfigService], useFactory: (config) => [{ ttl: config.get('TTL'), limit: config.get('LIMIT') }] }) ``` ``` -------------------------------- ### ThrottlerModule Source: https://github.com/nestjs/throttler/blob/master/_autodocs/GENERATION-SUMMARY.txt Documentation for the ThrottlerModule class, used for registering the module and its configurations. ```APIDOC ## ThrottlerModule ### Description Provides the core functionality for rate limiting in NestJS applications. ### Class ThrottlerModule ### Methods - `forRoot(options?: ThrottlerModuleOptions)`: Registers the module with global configuration. - `forRootAsync(options?: ThrottlerAsyncModuleOptions)`: Registers the module asynchronously with configuration. ### Configuration Options Refer to `configuration.md` for detailed configuration options. ``` -------------------------------- ### Asynchronous Provider Registration (forRootAsync) Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/providers.md Use `forRootAsync` for asynchronous registration, which supports factory functions, class providers, and existing providers for configuration. It also handles importing necessary modules. ```typescript static forRootAsync(options: ThrottlerAsyncOptions): DynamicModule { const providers = [ ...this.createAsyncProviders(options), ThrottlerStorageProvider ]; return { module: ThrottlerModule, imports: options.imports || [], providers, exports: providers, }; } ``` -------------------------------- ### Configure Multiple Throttler Definitions Source: https://github.com/nestjs/throttler/blob/master/README.md Set up multiple named throttling definitions with different ttl and limit values for granular control. ```typescript @@filename(app.module) @Module({ imports: [ ThrottlerModule.forRoot([ { name: 'short', ttl: 1000, limit: 3, }, { name: 'medium', ttl: 10000, limit: 20 }, { name: 'long', ttl: 60000, limit: 100 } ]), ], }) export class AppModule {} ``` -------------------------------- ### ThrottlerGuard Methods Source: https://github.com/nestjs/throttler/blob/master/_autodocs/INDEX.md Outlines the key methods of the `ThrottlerGuard` class, which implements rate limiting logic. ```typescript ThrottlerGuard (implements CanActivate) └─ canActivate(context) └─ handleRequest(requestProps) └─ getTracker(req) └─ getRequestResponse(context) └─ generateKey(context, suffix, name) └─ throwThrottlingException(context, throttlerLimitDetail) ``` -------------------------------- ### Store Throttler Limits Strategy Source: https://github.com/nestjs/throttler/blob/master/_autodocs/INDEX.md Choose the appropriate storage mechanism for throttler limits, such as in-memory, Redis, or a custom database implementation. ```markdown In-memory only? ├─ Default → ThrottlerStorageService In Redis? ├─ Implement ThrottlerStorage with Redis client In Database? ├─ Implement ThrottlerStorage with DB queries ``` -------------------------------- ### Utility Functions Source: https://github.com/nestjs/throttler/blob/master/_autodocs/INDEX.md Helper functions for defining time intervals for throttling limits and TTLs. ```APIDOC ## Utility Functions ### Description These utility functions provide a convenient way to specify time durations in milliseconds for rate-limiting configurations. ### Functions - `seconds(howMany: number): number` - `minutes(howMany: number): number` - `hours(howMany: number): number` - `days(howMany: number): number` - `weeks(howMany: number): number` ### Usage Use these functions when defining `ttl`, `blockDuration`, or within `ThrottlerOptions`. ```typescript import { ThrottlerModule } from '@nestjs/throttler'; import { minutes, seconds } from '@nestjs/throttler'; @Module({ imports: [ ThrottlerModule.forRoot([ { ttl: seconds(60), // 1 minute limit: 10, }, { ttl: minutes(5), // 5 minutes limit: 100, }, ]), ], }) export class AppModule {} ``` ``` -------------------------------- ### ThrottlerModule.forRoot Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/throttler-module.md Registers the ThrottlerModule synchronously with rate-limit configurations. This method accepts an array of throttler configurations or an object containing storage and global options. ```APIDOC ## ThrottlerModule.forRoot ### Description Registers the ThrottlerModule synchronously with rate-limit configurations. ### Method `static forRoot(options: ThrottlerModuleOptions = []): DynamicModule` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **options** (`ThrottlerModuleOptions`) - Optional - Array of throttler configurations or object with storage and global options ### Request Example ```typescript import { ThrottlerModule, seconds } from '@nestjs/throttler'; import { Module } from '@nestjs/common'; @Module({ imports: [ ThrottlerModule.forRoot([ { ttl: seconds(60), limit: 10, }, ]), ], }) export class AppModule {} ``` ### Response #### Success Response (200) `DynamicModule` — A Nest dynamic module that exports throttling providers. #### Response Example None ``` -------------------------------- ### Asynchronous ThrottlerModule Configuration with useClass Source: https://github.com/nestjs/throttler/blob/master/_autodocs/api-reference/throttler-module.md Use `forRootAsync` with `useClass` to register the ThrottlerModule asynchronously via a custom factory class. The factory class must implement `ThrottlerOptionsFactory`. ```typescript import { ThrottlerModule } from '@nestjs/throttler'; import { Module } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; class ThrottlerConfigService implements ThrottlerOptionsFactory { constructor(private configService: ConfigService) {} createThrottlerOptions(): ThrottlerModuleOptions { return [ { ttl: this.configService.get('THROTTLE_TTL'), limit: this.configService.get('THROTTLE_LIMIT'), }, ]; } } @Module({ imports: [ ThrottlerModule.forRootAsync({ useClass: ThrottlerConfigService, }), ], }) export class AppModule {} ``` -------------------------------- ### Dynamic Limits Configuration with ConfigService Source: https://github.com/nestjs/throttler/blob/master/_autodocs/configuration.md Configure throttler limits dynamically using environment variables via ConfigService. This allows for flexible limit adjustments without code changes. ```typescript import { Module } from '@nestjs/common'; import { ThrottlerModule } from '@nestjs/throttler'; import { ConfigModule, ConfigService } from '@nestjs/config'; @Module({ imports: [ ConfigModule.forRoot(), ThrottlerModule.forRootAsync({ imports: [ConfigModule], inject: [ConfigService], useFactory: (config: ConfigService) => [ { ttl: config.get('THROTTLE_TTL'), limit: config.get('THROTTLE_LIMIT'), }, ], }), ], }) export class AppModule {} ```