Retries sem efeitos duplicados: desenhar idempotência como contrato de API
Timeout não diz se o servidor falhou antes ou depois do efeito. Para repetir POST ou PATCH com segurança, cliente e servidor precisam de identidade da operação, fingerprint do pedido, estado de execução, resultado persistido e política de expiração.
- Natureza
- Guia de arquitetura baseado em RFC publicados, OpenAPI e um Internet-Draft expirado
- Âmbito
- APIs com efeitos materiais e clientes sujeitos a timeout/retry
- Publicado e verificado
- 4 de agosto de 2026
- Limite
- O contrato deve ser adaptado a transações, consistência e risco do domínio

Em resumo
HTTP define métodos idempotentes pela semântica pretendida, mas isso não torna qualquer implementação ou sequência automaticamente segura. Operações de criação, pagamento, envio ou alteração precisam de deduplicação no domínio. Uma chave deve ser única no âmbito do principal, operação e recurso; o servidor associa-a ao payload normalizado, conquista atomicamente o direito de executar e guarda status e resposta. Um replay igual recebe o resultado coerente; a mesma chave com payload diferente é rejeitada; pedidos concorrentes recebem estado explícito. O cliente só repete condições documentadas e usa backoff, jitter e limite.
- Idempotência HTTP descreve efeito pretendido de múltiplos pedidos iguais; não substitui transação, deduplicação ou reconciliação.
- A chave não deve ser global: inclua identidade/tenant, operação, recurso e fingerprint do conteúdo.
- O draft Idempotency-Key -07 expirou em 18 de abril de 2026 e não é RFC; use-o como input, não como norma publicada.
- Persistir apenas a chave sem estado e resultado cria corridas, respostas inconsistentes e duplicação após falha.
Semântica idempotente e execução única não são a mesma promessa
RFC 9110 define PUT, DELETE e métodos seguros como idempotentes em termos do efeito pretendido pelo cliente. Logs, métricas e outras consequências secundárias podem repetir. POST e PATCH não são idempotentes por definição, mas uma aplicação pode oferecer uma operação tolerante a retry por contrato.
O Internet-Draft de Idempotency-Key descreve boas ideias — unicidade, fingerprint, responsabilidades e erros — mas continua work in progress expirado. Documente o comportamento na OpenAPI e não afirme compatibilidade com um standard inexistente.
Estado de uma operação repetível
- RECEBERValidar âmbito e formato
Autenticar, autorizar e validar chave, operação, recurso e payload.
- RESERVARCriar registo atómico
Guardar chave composta e fingerprint com estado em progresso, ou ler existente.
- EXECUTARProduzir um efeito
Usar transação/outbox ou reconciliação adequada ao domínio.
- CONCLUIRPersistir resultado
Guardar status, representação ou referência, headers essenciais e tempo.
- REPLAYDevolver ou rejeitar
Resultado igual para fingerprint igual; conflito para conteúdo diferente.
- EXPIRARAplicar retenção explícita
Só reutilizar depois da janela contratual e com riscos de replay conhecidos.
Especificar todos os estados que o cliente pode observar
O happy path é a parte fácil. Documente resposta quando o primeiro pedido está em progresso, quando concluiu, quando falhou antes do efeito, quando o efeito é incerto, quando a chave mudou de payload e quando expirou. Use Problem Details para erros legíveis por máquina sem expor dados sensíveis.
Matriz de replay
| Estado guardado | Novo pedido | Resposta | Ação do cliente |
|---|---|---|---|
| Ausente | Chave e payload válidos | Aceitar e reservar | Aguardar resultado |
| Em progresso | Mesmo fingerprint | Conflito/in-progress + retry hint | Backoff com limite |
| Concluído | Mesmo fingerprint | Resultado persistido coerente | Não repetir efeito |
| Falhado antes do efeito | Mesmo fingerprint | Erro repetível ou nova tentativa controlada | Seguir contrato |
| Resultado incerto | Mesmo fingerprint | Pendente/reconciliação | Consultar estado, não recriar |
| Qualquer | Fingerprint diferente | Conflito de chave | Gerar nova operação |
| Expirado | Qualquer | Comportamento documentado | Não assumir deduplicação |
Testar nos pontos onde a rede corta a narrativa
Injete falha antes de reservar, depois de reservar, antes do commit, depois do commit e antes da resposta. Repita com dois pedidos simultâneos e com duas instâncias do servidor. Conte efeitos no sistema de registo, não apenas respostas HTTP.
Escolha retenção a partir da maior janela de retry, latência assíncrona, reconciliação e risco de operação duplicada. Para pagamentos ou efeitos irreversíveis, prefira consulta de estado e referência durável a adivinhar que falhou.
- Não usar a chave como segredo nem permitir que atravesse tenants.
- Aplicar rate limit sem apagar o registo de deduplicação.
- Guardar hash/fingerprint canónico sem conservar payload sensível desnecessário.
- Monitorizar replays, conflitos, operações presas, expirações e reconciliações.
Fontes consultadas
Consultadas na data de atualização indicada.
Abre numa nova janela.- 01RFC 9110 — HTTP SemanticsIETF · SYS-IETF
- 02Idempotency-Key HTTP Header Field — Internet-Draft -07IETF HTTPAPI Working Group · SYS-IETF
- 03RFC 9457 — Problem Details for HTTP APIsIETF · SYS-IETF
- 04OpenAPI Specification 3.1.0OpenAPI Initiative · SYS-OPENAPI
- 05RFC 6585 — Additional HTTP Status CodesIETF · SYS-IETF
- 06RFC 9111 — HTTP CachingIETF · SYS-IETF
Participar
Partilhe a análise. Acrescente contexto.
Divulgue a matéria no seu canal ou deixe uma observação ligada ao tema.

Comentários
A carregar a conversa.