Rate Limiting
Protecao contra abuso com limites globais e por rota.
Visao geral
Rate limiting protege sua API contra abuso, brute force e DDoS. O PlazerCLI configura limites globais com possibilidade de override por rota.
Configuracao padrao
| Variavel | Padrao | Descricao |
|---|---|---|
RATE_LIMIT_MAX | 100 | Maximo de requests por janela |
RATE_LIMIT_WINDOW_MS | 60000 | Janela de tempo em ms (1 minuto) |
NestJS — @nestjs/throttler
Usa o modulo oficial @nestjs/throttler com 3 presets de throttle:
@Module({
imports: [
ThrottlerModule.forRootAsync({
useFactory: (configService: ConfigService) => ({
throttlers: [
{ name: 'short', ttl: 10_000, limit: 10 }, // burst
{ name: 'medium', ttl: 60_000, limit: 100 }, // geral
{ name: 'long', ttl: 600_000, limit: 200 }, // sustentado
],
}),
}),
],
providers: [
{ provide: APP_GUARD, useClass: ThrottlerGuard },
],
})
export class ThrottleModule {}
O guard e registrado globalmente. Para pular throttle em uma rota:
import { SkipThrottle } from '@nestjs/throttler';
@SkipThrottle()
@Get('health')
health() { ... }
// Override de limite por rota:
@Throttle({ default: { limit: 5, ttl: 60000 } })
@Post('upload')
upload() { ... }
Express — express-rate-limit
Dois limiters pre-configurados sao gerados:
// Limiter padrao (100 req / 60s)
export const defaultLimiter = rateLimit({
windowMs: Number(process.env.RATE_LIMIT_WINDOW_MS) || 60_000,
max: Number(process.env.RATE_LIMIT_MAX) || 100,
standardHeaders: 'draft-7',
legacyHeaders: false,
});
// Limiter estrito para auth (10 req / 15min)
export const strictLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 10,
});
// Factory para criar limiters customizados
export function createLimiter(overrides) {
return rateLimit({ windowMs: 60_000, max: 100, ...overrides });
}
// Uso:
app.use('/api', defaultLimiter);
app.use('/api/auth', strictLimiter);
Fastify — @fastify/rate-limit
Plugin Fastify registrado globalmente:
async function rateLimiterPlugin(app: FastifyInstance) {
await app.register(rateLimit, {
max: Number(process.env.RATE_LIMIT_MAX) || 100,
timeWindow: Number(process.env.RATE_LIMIT_WINDOW_MS) || 60_000,
});
}
// Override por rota:
app.get('/heavy', {
config: { rateLimit: { max: 5, timeWindow: '1 minute' } }
}, handler);
// Desabilitar por rota:
app.get('/health', {
config: { rateLimit: false }
}, handler);
Resposta de erro (429)
// HTTP 429 Too Many Requests
{
"error": "Too Many Requests",
"message": "Too many requests, please try again later.",
"retryAfter": "30s"
}
// Headers retornados:
RateLimit-Limit: 100
RateLimit-Remaining: 0
RateLimit-Reset: 1708000000
Retry-After: 30