Skip to content

rate limit

awekrx edited this page May 29, 2026 · 1 revision

rate-limit

Import

import { rateLimit } from '@dev-suite/decorators/rate-limit'

Category

  • method

Use Case

Apply request quotas per time window.

Replaces

  • Timestamp arrays and window filtering in methods
  • Custom throttle guards in endpoints

Example 1

Without decorator

class LoginService {
  private attempts: number[] = [];

  requestOtp(phone: string) {
    const now = Date.now();
    this.attempts = this.attempts.filter((t) => now - t < 60_000);
    if (this.attempts.length >= 5) throw new Error('Too many requests');
    this.attempts.push(now);
    return this.otp.send(phone);
  }
}

With decorator

import { rateLimit } from '@dev-suite/decorators/rate-limit';

class LoginService {
  @rateLimit({ maxCalls: 5, windowMs: 60_000 })
  requestOtp(phone: string) {
    return this.otp.send(phone);
  }
}

Why better

  • Window policy is declared once and reused.
  • Method no longer manages timestamp state manually.

Example 2

Without decorator

class ApiService {
  private byUser = new Map<string, number[]>();

  call(userId: string) {
    const now = Date.now();
    const arr = this.byUser.get(userId) ?? [];
    const next = arr.filter((t) => now - t < 1000);
    if (next.length >= 10) throw new Error('Rate limited');
    next.push(now);
    this.byUser.set(userId, next);
    return this.remote.call();
  }
}

With decorator

import { rateLimit } from '@dev-suite/decorators/rate-limit';

class ApiService {
  @rateLimit({ maxCalls: 10, windowMs: 1000, keyResolver: ([userId]) => String(userId) })
  call(userId: string) {
    return this.remote.call();
  }
}

Why better

  • Per-user/per-tenant limits are easy with keyResolver.
  • Less bug-prone than custom throttling code.

Clone this wiki locally