Saltar para o conteúdo principal
Sistemas digitais13 min de leitura

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.

Atualizado
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
Dois pedidos físicos idênticos convergem num gate que produz um único artefacto e devolve o resultado do replay
Um retry seguro não ignora o segundo pedido: reconhece a mesma operação e devolve um resultado coerente sem repetir o efeito.Imagem gerada por IA sob direção editorial da Velqory.

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

  1. RECEBER
    Validar âmbito e formato

    Autenticar, autorizar e validar chave, operação, recurso e payload.

  2. RESERVAR
    Criar registo atómico

    Guardar chave composta e fingerprint com estado em progresso, ou ler existente.

  3. EXECUTAR
    Produzir um efeito

    Usar transação/outbox ou reconciliação adequada ao domínio.

  4. CONCLUIR
    Persistir resultado

    Guardar status, representação ou referência, headers essenciais e tempo.

  5. REPLAY
    Devolver ou rejeitar

    Resultado igual para fingerprint igual; conflito para conteúdo diferente.

  6. EXPIRAR
    Aplicar 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 guardadoNovo pedidoRespostaAção do cliente
AusenteChave e payload válidosAceitar e reservarAguardar resultado
Em progressoMesmo fingerprintConflito/in-progress + retry hintBackoff com limite
ConcluídoMesmo fingerprintResultado persistido coerenteNão repetir efeito
Falhado antes do efeitoMesmo fingerprintErro repetível ou nova tentativa controladaSeguir contrato
Resultado incertoMesmo fingerprintPendente/reconciliaçãoConsultar estado, não recriar
QualquerFingerprint diferenteConflito de chaveGerar nova operação
ExpiradoQualquerComportamento documentadoNã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.

Consultadas na data de atualização indicada.

  1. 01RFC 9110 — HTTP SemanticsIETF · SYS-IETF
  2. 02Idempotency-Key HTTP Header Field — Internet-Draft -07IETF HTTPAPI Working Group · SYS-IETF
  3. 03RFC 9457 — Problem Details for HTTP APIsIETF · SYS-IETF
  4. 04OpenAPI Specification 3.1.0OpenAPI Initiative · SYS-OPENAPI
  5. 05RFC 6585 — Additional HTTP Status CodesIETF · SYS-IETF
  6. 06RFC 9111 — HTTP CachingIETF · SYS-IETF