Integração e API

Chave de Idempotência

Para impedir que um timeout duplique pagamento, abertura de acesso ou criação de recurso, a chave de idempotência associa várias tentativas à mesma operação lógica. Um cliente gera um valor aleatório, como UUID de 128 bits, e o envia em `Idempotency-Key`. O servidor grava chave, hash do pedido e resultado por uma janela. A solução não torna qualquer comando idempotente automaticamente: reutilizar a chave com payload diferente deve falhar, e a retenção precisa superar o período de retry.


🔀 Tipos de Comunicação
HEADER
Cabeçalho HTTP por operação
O cliente envia um identificador em cabeçalho, normalmente `Idempotency-Key`, junto a POST, PATCH ou outra operação com efeito. A chave representa a intenção do usuário, não uma conexão de rede. Se a resposta se perde, o cliente repete o mesmo método, URL, corpo e chave. O servidor procura a chave no escopo correto, como conta, tenant e endpoint. Se já concluiu, retorna o resultado armazenado. Se ainda processa, pode aguardar, devolver conflito ou status de processamento. Se nunca viu, cria um registro de reserva e executa. A reserva precisa ser atômica para duas tentativas simultâneas não passarem. Um índice único no banco ou operação compare-and-set é comum. O cabeçalho não deve ser usado como credencial e não substitui autenticação.
REQUEST ID
Deduplicação por identificador no corpo
Algumas APIs usam `request_id`, `operation_id` ou `client_token` no JSON. O princípio é o mesmo, mas o identificador entra no contrato de domínio. Isso é útil em mensageria, lotes e integrações que não usam HTTP. Um comando de abrir válvula pode carregar `command_id`. O consumidor grava IDs processados. A chave precisa ser estável em retentativas e nova para uma nova intenção, mesmo se o payload for igual. Apertar “ligar” duas vezes em momentos diferentes pode ser uma ou duas intenções conforme a interface. O cliente define. Gerar a chave dentro de cada tentativa elimina o benefício. Reutilizar para sempre impede operações futuras. A documentação precisa definir ciclo de vida.
RESULT CACHE
Cache de resposta e estado de execução
O servidor pode guardar status code, cabeçalhos essenciais e corpo da primeira resposta. Uma repetição retorna a mesma representação. Se a primeira resposta foi 500, algumas implementações também armazenam; outras permitem nova tentativa. A política precisa ser explícita. O registro pode ter estados `in_progress`, `succeeded` e `failed`. Em operações longas, a chave pode apontar para um job. O cliente recebe 202 e consulta. A retenção exige armazenamento. Um milhão de operações por dia com metadados de 1 KB consome cerca de 1 GB diário antes de índices e replicação. TTL reduz. A janela deve cobrir retries, filas offline e latência do cliente. Apagar cedo reabre risco de duplicação.
INBOX
Idempotência em consumidores de mensagens
Brokers com entrega pelo menos uma vez podem reenviar. O consumidor usa `message_id` como chave e mantém uma inbox de processados. A gravação do ID e do efeito deve ocorrer na mesma transação quando possível. Caso contrário, existe janela: gravar ID antes pode perder o efeito; depois pode duplicar. O padrão transactional inbox combina. Em sistemas externos, usa-se uma chave de idempotência na API chamada. Uma automação que recebe duas vezes “definir brilho em 70%” produz o mesmo estado; uma que recebe “incrementar 10%” duplica. Preferir comandos absolutos simplifica. Efeitos físicos podem não ser reversíveis, portanto deduplicação deve ocorrer antes do comando.
✅ Vantagens Arquiteturais
Torna retentativas seguras em redes instáveis
Timeout não revela se o servidor executou. Sem chave, o cliente escolhe entre não repetir e perder a ação ou repetir e duplicar. Com chave, repete. O servidor reconhece. Isso é especialmente relevante em 4G, Wi‑Fi instável e APIs de nuvem. A garantia depende da durabilidade do registro e do escopo. Se duas instâncias usam caches locais separados, ambas podem executar. O armazenamento precisa ser compartilhado ou a requisição roteada de forma consistente, mas sticky session isolada é frágil. A chave também precisa sobreviver a reinício. Redis persistente, banco relacional ou store distribuído são opções. A latência adicional é o custo.
Evita efeitos duplicados em operações não naturalmente idempotentes
HTTP define PUT e DELETE como idempotentes na semântica pretendida, mas POST não possui garantia. Criar uma cena, emitir cobrança, enviar convite ou acionar job pode duplicar. A chave transforma a operação de negócio numa execução única dentro da janela. Não resolve efeitos externos se o servidor chama um dispositivo e falha antes de registrar. O fluxo precisa usar transação, outbox ou repassar a mesma chave ao provedor. Em automação, comandos de pulso e toggle são perigosos. O endpoint deve preferir `set_state` e usar chave para ações. O design do comando ainda importa.
Permite correlação e auditoria por intenção
A chave aparece em logs, traces, jobs e mensagens. O suporte pode rastrear uma operação da API ao gateway e ao dispositivo. É útil quando o usuário relata que a porta abriu duas vezes. A chave não deve conter e-mail, endereço ou dados pessoais. Use UUID v4, UUID v7, ULID ou valor criptograficamente aleatório. UUID de 128 bits reduz colisão a nível desprezível quando bem gerado. A chave pode ser propagada como metadado, mas não confundida com `trace_id`: uma intenção pode atravessar várias tentativas e traces. Ambos são úteis e distintos.
Protege processamento em lote contra retransmissão total
Uma Batch API pode ter chave do lote e chaves por item. Se a resposta geral se perde, o cliente reenvia. O servidor retorna resultados anteriores e processa apenas itens novos conforme política. Isso reduz duplicação. A chave do lote não basta se o servidor aceita alterações parciais; cada suboperação precisa de identidade. Um item falho e retentável pode usar a mesma chave para obter conclusão. O contrato deve definir se payload corrigido exige nova chave. Em geral, mesma chave com conteúdo diferente retorna 409 ou erro. Isso evita substituir silenciosamente a intenção armazenada.
Cria base para consistência entre API e mensageria
A requisição entra com chave. A aplicação grava recurso e evento de outbox na mesma transação. O publicador envia evento com `operation_id`. Consumidores deduplicam. Essa cadeia reduz efeitos duplicados. Não cria exactly-once universal; cria processamento efetivamente único em limites definidos. A documentação deve declarar. O usuário precisa saber se repetir após 24 h ainda é deduplicado. Em dispositivos, a confirmação física pode permanecer incerta. A API pode garantir uma única emissão de comando, não que o atuador não reiniciou e repetiu. Limites honestos são essenciais.