Pular para o conteúdo

Limites de Requisição

A API External do Efflux implementa rate limiting para garantir uso justo e estabilidade do sistema. Entender esses limites ajuda você a construir integrações confiáveis.

Limites Atuais

Tipo de LimiteValorJanela
Requisições por minuto60Janela rolante de 1 minuto
Requisições por hora1.000Janela rolante de 1 hora
Requisições por dia10.000Janela rolante de 24 horas

Headers de Rate Limit

Informações de rate limit são incluídas nos headers de resposta:

HeaderDescrição
X-RateLimit-LimitMáximo de requisições permitidas na janela atual
X-RateLimit-RemainingRequisições restantes na janela atual
X-RateLimit-ResetTimestamp Unix de quando a janela reseta

Exemplo de Headers de Resposta

HTTP/1.1 200 OK
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1705764900

Rate Limit Excedido

Quando você excede o rate limit, a API retorna uma resposta 429 Too Many Requests:

{
"error": "Rate limit exceeded",
"code": "RATE_LIMIT_EXCEEDED"
}

A resposta inclui um header Retry-After indicando quantos segundos esperar:

HTTP/1.1 429 Too Many Requests
Retry-After: 30

Tratando Rate Limits

1. Monitore os Headers de Rate Limit

Acompanhe seu uso lendo os headers de rate limit:

async function fetchWithRateLimitAwareness(url, options) {
const response = await fetch(url, options);
const limit = response.headers.get('X-RateLimit-Limit');
const remaining = response.headers.get('X-RateLimit-Remaining');
const reset = response.headers.get('X-RateLimit-Reset');
if (remaining !== null) {
console.log(`Rate limit: ${remaining}/${limit} restantes`);
if (parseInt(remaining) < 10) {
console.warn('Aproximando-se do rate limit');
}
}
return response;
}

2. Implemente Retry com Backoff

Quando atingir um rate limit, use o header Retry-After:

async function fetchWithRetry(url, options, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After');
const waitSeconds = retryAfter ? parseInt(retryAfter) : Math.pow(2, attempt);
console.log(`Rate limited. Aguardando ${waitSeconds}s antes de tentar novamente...`);
await sleep(waitSeconds * 1000);
continue;
}
return response;
}
throw new Error('Máximo de tentativas excedido');
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}

3. Implemente Fila de Requisições

Para aplicações de alto volume, enfileire requisições para ficar dentro dos limites:

class RateLimitedQueue {
constructor(requestsPerSecond = 1) {
this.queue = [];
this.processing = false;
this.minInterval = 1000 / requestsPerSecond;
this.lastRequest = 0;
}
async add(requestFn) {
return new Promise((resolve, reject) => {
this.queue.push({ requestFn, resolve, reject });
this.process();
});
}
async process() {
if (this.processing || this.queue.length === 0) return;
this.processing = true;
while (this.queue.length > 0) {
const now = Date.now();
const timeSinceLastRequest = now - this.lastRequest;
if (timeSinceLastRequest < this.minInterval) {
await sleep(this.minInterval - timeSinceLastRequest);
}
const { requestFn, resolve, reject } = this.queue.shift();
try {
this.lastRequest = Date.now();
const result = await requestFn();
resolve(result);
} catch (error) {
reject(error);
}
}
this.processing = false;
}
}
// Uso
const queue = new RateLimitedQueue(1); // 1 requisição por segundo
const results = await Promise.all([
queue.add(() => fetchContent()),
queue.add(() => fetchPlayers()),
queue.add(() => fetchSchedules()),
]);

Boas Práticas

1. Use Cache nas Respostas

Reduza chamadas à API fazendo cache das respostas:

const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutos
async function getCachedContent() {
const cached = cache.get('content');
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
return cached.data;
}
const data = await fetchContent();
cache.set('content', { data, timestamp: Date.now() });
return data;
}

2. Use Webhooks (Em Breve)

3. Agrupe Requisições Relacionadas

Se você precisa de dados de múltiplos endpoints, faça requisições concorrentes mas esteja atento ao rate limit:

// Bom: Requisições concorrentes (ainda conta contra o rate limit)
const [content, players, schedules] = await Promise.all([
fetchContent(),
fetchPlayers(),
fetchSchedules()
]);
// Melhor: Com consciência do rate limit
async function fetchAllData() {
const remaining = await getRateLimitRemaining();
if (remaining < 3) {
// Aguardar reset do rate limit
await waitForReset();
}
return Promise.all([
fetchContent(),
fetchPlayers(),
fetchSchedules()
]);
}

4. Otimize Intervalos de Polling

Se você está fazendo polling por atualizações, use intervalos razoáveis:

Caso de UsoIntervalo Recomendado
Atualizações de dashboard30-60 segundos
Monitoramento de players1-5 minutos
Atualização de analytics5-15 minutos
Sincronização de conteúdo5-10 minutos
// Polling com intervalo adaptativo
async function pollWithBackoff(fetchFn, baseInterval = 30000) {
let interval = baseInterval;
while (true) {
try {
const data = await fetchFn();
// Reset para intervalo base em sucesso
interval = baseInterval;
// Processar dados...
} catch (error) {
if (error.status === 429) {
// Dobrar intervalo em rate limit (máx 5 minutos)
interval = Math.min(interval * 2, 5 * 60 * 1000);
}
}
await sleep(interval);
}
}

5. Trate Rate Limits Graciosamente na UI

Mostre feedback significativo aos usuários quando houver rate limit:

try {
const data = await fetchContent();
displayContent(data);
} catch (error) {
if (error.status === 429) {
showNotification(
'Estamos recebendo muitas requisições. Por favor, aguarde um momento e tente novamente.',
'warning'
);
}
}

Monitorando Seu Uso

Acompanhe seus padrões de uso da API para ficar dentro dos limites:

  1. Registre todas as requisições com timestamps
  2. Monitore os headers de rate limit nas respostas
  3. Configure alertas ao se aproximar dos limites
  4. Revise o uso periodicamente para otimizar