Overview
The @RateLimiter decorator restricts the number of incoming requests to a route within a defined time window. Once
the limit is exceeded, subsequent requests are rejected with an appropriate status code.
Import
import { RateLimiter } from '@heronjs/common';Signature
@RateLimiter({
windows: number; // Time window in milliseconds
max: number; // Max number of requests allowed in the window
key: (req) => string; // Function to extract a unique key (IP, token, user-id, etc.)
})| Property | Type | Description |
|---|---|---|
windows | number | Duration of the rate-limit window (in milliseconds). |
max | number | Maximum allowed requests per window. |
key | (req) => string | Returns a unique identifier for the client. |
Key Extraction Examples
The key callback receives the raw Express HttpRequest object (rq). You can extract any header or property to
differentiate clients.
1. Rate limit by IP address
@Get({ uri: '/liveness' })
@RateLimiter({ windows: 60000, max: 5, key: (rq) => `${rq.ip}` })
liveness(@Queries() a: {}): Observable<OutputProps> {
}2. Rate limit by Authorization header
@Get({ uri: '/secure-data' })
@RateLimiter({
windows: 30000,
max: 3,
key: (rq) => `${rq.headers['authorization'] ?? 'anonymous'}`,
})
secureData(@Queries() a: {}): Observable<OutputProps> {
}3. Rate limit by custom header (e.g., x-api-key)
@Get({ uri: '/api' })
@RateLimiter({
windows: 60000,
max: 10,
key: (rq) => `${rq.headers['x-api-key'] ?? rq.ip}`,
})
apiEndpoint(@Queries() a: {}): Observable<OutputProps> {
}4. Combining IP and User-Agent
@Get({ uri: '/search' })
@RateLimiter({
windows: 60000,
max: 20,
key: (rq) => `${rq.ip}-${rq.headers['user-agent'] ?? 'unknown'}`,
})
search(@Queries() a: {}): Observable<OutputProps> {
}Full Example with Circuit Breaker
import { Get, Queries, RateLimiter, CircuitBreaker } from '@heronjs/core';
import { Observable, of } from 'rxjs';
@Get({ uri: '/liveness' })
@RateLimiter({ windows: 60000, max: 1, key: (rq) => `${rq.ip}` })
// @CircuitBreaker<HealthCheckRest>({ threshold: 3, cooldown: 60000, fallback: 'fallback' })
liveness(@Queries() a: {}): Observable<OutputProps> {
}
fallback(): Observable<{ status: string }> {
});
}Important Notes
- The rate-limiter uses an in-memory sliding-window counter. Restarting the process resets all counters.
- When the limit is exceeded, the framework responds with HTTP 429 Too Many Requests.
- Combine
@RateLimiterwith@CircuitBreakerfor advanced resilience patterns (see the Circuit Breaker documentation).
Last updated on