NestJS Adapter

The NestJS adapter provides a module, guard, and decorator for seamless integration with NestJS applications.

Installation

npm install @joint-ops/hitlimit
pnpm add @joint-ops/hitlimit
yarn add @joint-ops/hitlimit
bun add @joint-ops/hitlimit

Module Setup

Import the HitlimitModule in your app module:

app.module.ts
import { Module } from '@nestjs/common'
import { HitlimitModule } from '@joint-ops/hitlimit/nest'

@Module({
  imports: [
    HitlimitModule.forRoot({
      limit: 100,
      window: '1m'
    })
  ]
})
export class AppModule {}

Async Configuration

Use async configuration for dynamic settings:

app.module.ts
HitlimitModule.forRootAsync({
  imports: [ConfigModule],
  inject: [ConfigService],
  useFactory: (config: ConfigService) => ({
    limit: config.get('RATE_LIMIT'),
    window: config.get('RATE_WINDOW')
  })
})

Using the Guard

Apply rate limiting globally or per controller:

main.ts
import { HitlimitGuard } from '@joint-ops/hitlimit/nest'

async function bootstrap() {
  const app = await NestFactory.create(AppModule)

  // Apply globally
  app.useGlobalGuards(new HitlimitGuard())

  await app.listen(3000)
}

Using the Decorator

Apply custom limits to specific routes using the @RateLimit decorator:

users.controller.ts
import { Controller, Get, Post } from '@nestjs/common'
import { RateLimit } from '@joint-ops/hitlimit/nest'

@Controller('users')
export class UsersController {

  @Get()
  @RateLimit({ limit: 100, window: '1m' })
  findAll() {
    return this.usersService.findAll()
  }

  @Post('login')
  @RateLimit({ limit: 5, window: '15m' })
  login() {
    return this.authService.login()
  }
}

Skip Rate Limiting

Use the @SkipRateLimit decorator to bypass rate limiting:

import { SkipRateLimit } from '@joint-ops/hitlimit/nest'

@Get('health')
@SkipRateLimit()
healthCheck() {
  return { status: 'ok' }
}

Custom Key Extraction

Extract rate limit key from the execution context:

HitlimitModule.forRoot({
  limit: 100,
  window: '1m',
  key: (context) => {
    const request = context.switchToHttp().getRequest()
    return request.user?.id || request.ip
  }
})

Using with Stores

Configure a Redis store for distributed deployments:

import { redisStore } from '@joint-ops/hitlimit/stores/redis'

HitlimitModule.forRoot({
  limit: 100,
  window: '1m',
  store: redisStore({
    url: 'redis://localhost:6379'
  })
})

Next Steps