Pular para o conteúdo principal

Segurança

Proteja sua Chave de API

  • Nunca exponha em código-fonte público
  • Use variáveis de ambiente
  • Não inclua em logs

Use HTTPS

  • Sempre use HTTPS para requisições
  • Verifique certificados SSL
  • Não aceite certificados inválidos

Defina Expiração

  • Configure datas de expiração para chaves
  • Rotacione chaves periodicamente
  • Revogue chaves comprometidas imediatamente

Princípio do Menor Privilégio

  • Crie chaves com permissões mínimas necessárias
  • Use chaves diferentes para ambientes diferentes
  • Delete chaves não utilizadas

Tratamento de Erros

1

Sempre Verifique o Status HTTP

Não assuma sucesso - verifique o código de status em toda requisição.
if (!response.ok) {
  const error = await response.json();
  console.error('Erro:', error.error.message);
}
2

Implemente Retry Logic

Para erros temporários (5xx, 429), implemente retry com backoff exponencial.
const delay = Math.pow(2, attempt) * 1000; // 1s, 2s, 4s, 8s...
await new Promise(r => setTimeout(r, delay));
3

Use Timeouts Apropriados

Configure timeouts para evitar requisições penduradas.
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 30000);

const response = await fetch(url, {
  signal: controller.signal
});
4

Trate Erros Específicos

Implemente handlers para diferentes tipos de erro.
switch (response.status) {
  case 401: handleAuthError(); break;
  case 404: handleNotFound(); break;
  case 429: handleRateLimit(); break;
}

Performance

  • Implemente cache local quando apropriado
  • Use filtros para buscar apenas dados necessários
  • Agrupe operações quando possível
  • Sempre use limit e offset para listas grandes
  • Não tente buscar todos os dados de uma vez
  • Processe dados em lotes
let offset = 0;
const limit = 50;

while (true) {
  const response = await fetch(
    `${url}?limit=${limit}&offset=${offset}`
  );
  const data = await response.json();

  if (data.length === 0) break;

  processData(data);
  offset += limit;
}
  • Monitore headers de rate limit
  • Implemente throttling do lado do cliente
  • Use filas para operações em massa
  • Registre latências das requisições
  • Configure alertas para degradação
  • Use métricas para identificar problemas

Webhooks

Responda Rápido

Retorne 200 rapidamente e processe em background. Webhooks têm timeout.

Idempotência

Processe eventos de forma idempotente - o mesmo evento pode ser enviado mais de uma vez.

Valide Payloads

Sempre valide a estrutura do payload antes de processar.

Log Eventos

Registre todos os eventos recebidos para debugging e auditoria.

Exemplo de Cliente Robusto

class LeavoClient {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.baseUrl = 'https://api.leavo.ai';
  }

  async request(method, path, data = null, retries = 3) {
    for (let attempt = 0; attempt < retries; attempt++) {
      try {
        const response = await fetch(`${this.baseUrl}${path}`, {
          method,
          headers: {
            'Authorization': `Bearer ${this.apiKey}`,
            'Content-Type': 'application/json'
          },
          body: data ? JSON.stringify(data) : null,
          signal: AbortSignal.timeout(30000)
        });

        if (response.status === 429) {
          const retryAfter = response.headers.get('Retry-After') || 60;
          await this.sleep(retryAfter * 1000);
          continue;
        }

        if (response.status >= 500) {
          await this.sleep(Math.pow(2, attempt) * 1000);
          continue;
        }

        if (!response.ok) {
          const error = await response.json();
          throw new Error(error.error?.message || 'Request failed');
        }

        return response.status === 204 ? null : response.json();
      } catch (error) {
        if (attempt === retries - 1) throw error;
        await this.sleep(Math.pow(2, attempt) * 1000);
      }
    }
  }

  sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

  // Métodos de conveniência
  getLeads(params = {}) {
    const query = new URLSearchParams(params).toString();
    return this.request('GET', `/backend/leads?${query}`);
  }

  createLead(data) {
    return this.request('POST', '/backend/leads', data);
  }

  updateLead(id, data) {
    return this.request('PUT', `/backend/leads/${id}`, data);
  }

  deleteLead(id) {
    return this.request('DELETE', `/backend/leads/${id}`);
  }
}

// Uso
const client = new LeavoClient(process.env.LEAVO_API_KEY);
const leads = await client.getLeads({ limit: 50 });