Pular para o conteudo principal

Idempotência em APIs

O que e idempotencia, por que ela importa em sistemas distribuidos e como implementar de forma que redes instaveis não corrompam dados.

Andrews Ribeiro

Andrews Ribeiro

Founder & Engineer

Trilha

Trilha de system design para entrevistas

Etapa 13 / 19

O problema

Rede falha. Cliente tenta de novo. Timeout acontece. Mensagem reaparece.

Esse e o tipo de comportamento que parece exceção até o dia em que vira incidente.

Se um usuário tenta pagar R$100, não recebe resposta e clica de novo, o que seu sistema faz?

Se a resposta for “cobra duas vezes”, não e um detalhe operacional. E um bug serio.

Modelo mental

Idempotencia, em linguagem simples, e isto:

fazer a mesma operação mais de uma vez e terminar no mesmo estado final

O foco aqui e no efeito final, não no número de vezes que o código executou.

Exemplo fácil:

  • DELETE /users/123 costuma ser idempotente. Depois da primeira vez, repetir continua deixando o usuário apagado.

Exemplo não idempotente:

  • POST /charges cria uma cobrança nova a cada repetição.

Em sistema distribuido, idempotencia importa porque repetição não e raridade. E comportamento normal do ambiente.

Quebrando o problema

Quais metodos HTTP sao idempotentes e por que

Em termos de semântica HTTP, GET, PUT e DELETE costumam ser tratados como idempotentes.

POST normalmente não e, porque costuma significar “crie algo novo”.

Mas a entrevista não costuma parar nessa definição formal.

O que importa e:

  • essa operação pode chegar de novo?
  • se chegar, o resultado precisa continuar sendo um só?

Idempotency key: o padrão correto

O jeito mais comum de tornar um POST crítico seguro e usar uma chave de idempotencia.

Fluxo simples:

  1. o cliente manda a requisição com uma chave unica
  2. o servidor guarda essa chave associada ao resultado
  3. se a mesma chave chegar de novo, o servidor devolve o mesmo resultado em vez de criar tudo outra vez

Isso funciona muito bem para:

  • pagamento
  • criação de pedido
  • operação cara que não pode duplicar

Como implementar: Redis vs banco de dados

Redis costuma aparecer quando você quer resposta rápida e TTL simples.

Banco de dados faz sentido quando o próprio registro principal pode carregar essa garantia ou quando a durabilidade precisa ser maior.

O desenho exato depende do caso, mas a ideia central não muda:

  • identificar a operação repetida
  • vincular isso a uma chave
  • devolver o resultado anterior em vez de processar de novo

O detalhe senior aqui e decidir o que exatamente a chave representa. Ela precisa apontar para a mesma intenção de negócio, não só para “duas requests parecidas”. Se a mesma chave puder significar operações diferentes, você trocou duplicidade por comportamento incorreto.

Idempotencia em consumidores de fila

Fila com entrega repetida faz esse assunto reaparecer fora do HTTP.

Se o consumidor receber a mesma mensagem de order_paid duas vezes, ele não pode:

  • criar dois pedidos
  • mandar dois estornos
  • baixar estoque duas vezes

O mecanismo pode ser outro, mas a pergunta e igual:

como eu reconheco que isso já foi processado?

TTL e expiração de idempotency keys

A chave não precisa viver para sempre em todo caso.

Ela precisa viver tempo suficiente para cobrir a janela real de repetição.

Se a operação pode ser tentada de novo por minutos ou horas, o TTL precisa refletir isso. Se expirar cedo demais, o retry tardio pode virar duplicidade. Se viver para sempre sem critério, você acumula custo e ruina operacional desnecessaria.

Também precisa decidir o que fazer quando a primeira tentativa ainda esta em andamento. Em alguns fluxos, a segunda chamada deve receber o mesmo resultado depois. Em outros, faz sentido responder algo como “ainda processando”. O importante e o comportamento ser previsivel.

Exemplo simples

Imagine um endpoint de pagamento.

O cliente manda:

  • valor
  • metodo de pagamento
  • idempotency_key

O servidor recebe, verifica se aquela chave já existe:

  • se não existe, processa, salva o resultado e responde
  • se já existe, devolve o mesmo resultado anterior

Agora, se o cliente tiver timeout depois do processamento e repetir, a segunda chamada não cobra de novo.

Esse e o valor real da idempotencia: transformar repetição inevitavel em comportamento seguro.

Erros comuns

  • Achar que retry e raro demais para preocupar.
  • Confiar só no cliente para não repetir.
  • Usar idempotencia só no HTTP e esquecer fila.
  • Expirar a chave cedo demais.
  • Confundir “não repetir chamada” com “suportar repetição se acontecer”.

Como um senior pensa

Quem tem mais experiência costuma tratar repetição como fato do ambiente, não como azar.

O raciocínio normalmente e:

“Se a mesma intenção chegar duas vezes, eu preciso de um jeito claro de reconhecer isso e impedir efeito colateral duplo.”

Essa postura ajuda muito porque coloca a pergunta certa no centro. Não e “sera que vai repetir?”. E “o que acontece quando repetir?”.

Isso também melhora o desenho da API. Em vez de discutir só endpoint e payload, você passa a discutir garantia operacional.

O que o entrevistador quer ver

Em entrevista, idempotencia mostra maturidade operacional rápido.

O entrevistador quer ver se você:

  • entende por que timeout e retry tornam repetição inevitavel
  • sabe explicar o papel da idempotency key
  • conecta HTTP e fila ao mesmo problema
  • pensa em janela de validade e persistencia da chave

Idempotencia não deixa a rede mais confiavel. Ela deixa o seu sistema menos fragil quando a rede se comporta como rede.

Resumo rápido

O que vale manter na cabeça

Checklist de pratica

Use isto ao responder

Você concluiu este artigo

Parte da trilha: Trilha de system design para entrevistas (13/19)

Próximo artigo Consistent hashing na prática Artigo anterior Consistência forte vs eventual

Continue explorando

Artigos relacionados