Boas Práticas de Integração
Um guia rápido para garantir que sua integração seja segura, resiliente e pronta para produção.
Segurança
Armazenamento de credenciais
Nunca coloque ACCESS_TOKEN ou SECRET_KEY diretamente no código-fonte. Use variáveis de ambiente:
// Correto
const accessToken = process.env.FROTA_ACCESS_TOKEN;
const secretKey = process.env.FROTA_SECRET_KEY;
// Errado — nunca faça isso
const accessToken = 'meu_token_fixo'; // ❌
Em produção, prefira um secret manager (AWS Secrets Manager, HashiCorp Vault, etc.).
Use HTTPS sempre
Todas as requisições devem usar HTTPS. O ambiente de homologação e produção já exigem HTTPS.
Não exponha credenciais em logs
// Correto — logar sem expor a chave
console.log('Chamando API:', { url, method });
// Errado — expõe credenciais
console.log('Headers:', { authorization: headers.authorization }); // ❌
Resiliência
Implemente retry com backoff
Para erros temporários (HTTP 5xx), tente novamente com espera crescente:
async function chamarComRetry(url, opcoes, tentativas = 3) {
for (let i = 0; i < tentativas; i++) {
const resposta = await fetch(url, opcoes);
if (resposta.ok) return resposta;
// Erros 4xx não devem ter retry (exceto 429)
if (resposta.status >= 400 && resposta.status < 500 && resposta.status !== 429) {
throw new Error(`Erro HTTP ${resposta.status}`);
}
// Espera: 1s, 2s, 4s
const espera = Math.pow(2, i) * 1000;
await new Promise(r => setTimeout(r, espera));
}
throw new Error('Número máximo de tentativas atingido');
}
Respeite o header Retry-After
Se receber HTTP 429, aguarde o tempo indicado antes de tentar novamente:
if (resposta.status === 429) {
const espera = parseInt(resposta.headers.get('Retry-After') || '60');
await new Promise(r => setTimeout(r, espera * 1000));
}
Performance
Use paginação adequada
Não busque todos os registros de uma vez. Use páginas menores e processe em lotes:
const PAGINA_TAMANHO = 50;
let pagina = 1;
while (true) {
const dados = await buscarPagina(pagina, PAGINA_TAMANHO);
await processarLote(dados.data);
if (pagina >= dados.pagination.totalPages) break;
pagina++;
}
Prefira webhooks para atualizações em tempo real
Em vez de fazer polling (verificar periodicamente se há novidades), configure webhooks para receber eventos conforme acontecem. Isso reduz o número de requisições e garante resposta mais rápida.
Veja Webhooks.
Cache de dados estáticos
Dados como listas de empresas, divisões e grupos de usuários mudam raramente. Armazene em cache para evitar chamadas desnecessárias:
let empresasCache = null;
let cacheTimestamp = 0;
const CACHE_TTL = 5 * 60 * 1000; // 5 minutos
async function obterEmpresas() {
if (empresasCache && Date.now() - cacheTimestamp < CACHE_TTL) {
return empresasCache;
}
empresasCache = await buscarEmpresas();
cacheTimestamp = Date.now();
return empresasCache;
}
Viagens e indicação de condutores
Prefira viagens à indicação manual
O endpoint de indicação manual (/key/tickets/indicate-driver) é útil para casos pontuais. Para fluxos regulares, use viagens: ao registrar a viagem com o condutor e o intervalo, todas as multas e notificações do período são vinculadas automaticamente.
Feche viagens abertas
Viagens sem endDate continuam vinculando novos eventos ao condutor indefinidamente. Sempre defina a data de fim ao encerrar uma viagem, ou atualize via PUT /key/trips/{id}.
Checklist de integração
Antes de ir para produção, verifique:
- Credenciais armazenadas em variáveis de ambiente
- HMAC calculado corretamente em todas as requisições
- Retry com backoff para erros 5xx
- Respeito ao
Retry-Afterem erros 429 - Webhook cadastrado para eventos relevantes
- Endpoint de webhook responde HTTP 200 em até 5s
- Endpoint de webhook valida a assinatura HMAC recebida
- Endpoint de webhook trata entregas duplicadas via campo
id - Testado no ambiente de homologação
Dúvidas ou problemas? Entre em contato em suporte@frota162.com.br.