O que é idempotência?

Em ciência da computação, idempotência é uma propriedade de uma operação em que aplicá-la várias vezes tem o mesmo efeito final que aplicá-la apenas uma vez. Se você enviar a mesma solicitação para um servidor cinco vezes, um sistema idempotente garante que o resultado no servidor não mude após a primeira tentativa bem-sucedida.

Além de garantir o mesmo resultado, uma característica fundamental das operações idempotentes é que elas não produzem efeitos colaterais com chamadas adicionais. Esse é um requisito essencial para a criação de sistemas distribuídos resilientes em que interrupções de rede intermitentes ou tempos limite podem fazer com que um cliente envie a mesma mensagem mais de uma vez.

Analogia: pense no botão "para cima" de um elevador. Se você pressionar uma vez, o elevador será chamado para o seu andar. Se você apertar o botão mais dez vezes enquanto espera, o resultado será o mesmo: um elevador vai chegar ao seu andar. Pressionar o botão várias vezes não vai chamar dez elevadores separados. Por outro lado, adicionar um item a um carrinho de compras digital geralmente não é idempotente. Se você clicar no botão "Adicionar ao carrinho" cinco vezes, provavelmente vai acabar com cinco itens no seu carrinho.

Principais benefícios dos sistemas idempotentes

Tente novamente as solicitações com segurança após um tempo limite ou queda de conexão sem medo de duplicar ações (como cobrar duas vezes um cartão de crédito).

Os usuários não precisam de um rastreamento de estado complexo para saber se uma solicitação anterior foi bem-sucedida. Eles podem simplesmente "tentar novamente até ter sucesso".

Os sistemas distribuídos podem se recuperar de falhas reproduzindo registros ou reenviando mensagens perdidas sem corromper os dados.

Métodos HTTP idempotentes e não idempotentes

O padrão REST define como diferentes tipos de solicitações da web devem se comportar. Alguns métodos HTTP são naturalmente "seguros" ou idempotentes por design, ou seja, a especificação espera que eles se comportem de forma previsível mesmo quando repetidos. Outros são projetados para criar novos dados e exigem mais cuidado para serem seguros para novas tentativas.

Métodos idempotentes (GET, PUT, DELETE)

De acordo com a RFC 9110, vários métodos padrão são inerentemente idempotentes. A repetição dessas ações não deve mudar o estado do servidor além da solicitação inicial.

  • GET: esse método recupera dados. Como ele não muda nada no servidor, você pode chamá-lo um milhão de vezes e o recurso permanece o mesmo.
  • PUT: esse método substitui um recurso por completo. Se você atualizar o e-mail de um usuário para "usuario@exemplo.com" três vezes, o estado final ainda será que o e-mail é "usuario@exemplo.com".
  • DELETE: remove um recurso. Se você excluir o "Pedido nº 123" e tentar excluí-lo de novo, ele vai continuar excluído. O resultado (a ordem desapareceu) permanece o mesmo.

Métodos não idempotentes (POST, PATCH)

Alguns métodos não são idempotentes porque o principal trabalho deles é mudar os dados de uma forma que cria algo novo ou modifica uma parte de um registro atual.

  • POST: os desenvolvedores usam POST para criar novos recursos. Sem a lógica de idempotência, o envio da mesma solicitação POST duas vezes (como "Enviar pagamento") normalmente resultaria em dois registros separados e duas cobranças ao cliente.
  • PATCH: esse método aplica atualizações parciais. Embora possa ser idempotente, geralmente não é por padrão, porque repetir uma mudança relativa (como "adicionar 5 ao saldo") resultaria em um valor final diferente a cada vez que é chamado.

Como implementar uma API idempotente

  1. Gerar uma chave exclusiva: o cliente cria uma string exclusiva (como um UUID) e a inclui em um cabeçalho HTTP personalizado.
  2. Interceptar e validar: o servidor verifica um repositório de dados de alta velocidade, como o Memorystore, para saber se essa chave foi processada recentemente.
  3. Gerenciar o estado: se a chave for nova, processe a solicitação e salve o resultado. Se for duplicado, retorne o resultado armazenado imediatamente sem executar novamente a lógica de negócios.

Casos de uso comuns para idempotência

A idempotência é frequentemente necessária nos sistemas que criamos. Em alguns casos, isso é feito por nós. Em outros casos, nós, como desenvolvedores, precisamos agir para que isso aconteça.

O exemplo mais famoso é o problema da "cobrança dupla". Se o navegador de um usuário travar enquanto ele estiver pagando por um voo, ele poderá clicar em "Pagar" novamente. Uma API de pagamento que usa uma chave de idempotência garante que o segundo clique seja reconhecido como uma nova tentativa. Isso protege a conta bancária do cliente e reduz o custo operacional de lidar com reembolsos de transações duplicadas.

  • Ação necessária do desenvolvedor: você precisa implementar uma chave de idempotência (geralmente um UUID) na sua solicitação de API para garantir que o segundo clique seja reconhecido como uma nova tentativa, protegendo a conta bancária do cliente

Ferramentas como Terraform e Ansible dependem da idempotência. Quando você executa um script para "criar um bucket de armazenamento de 10 GB", a ferramenta verifica o estado atual da sua nuvem.

  • Gerenciamento automático: a idempotência é gerenciada pela própria ferramenta de IaC. Como desenvolvedor, você não precisa escrever lógica extra para evitar recursos duplicados.

As APIs da web modernas costumam implementar o cabeçalho Idempotency-Key (agora um rascunho padronizado da IETF) para permitir que os desenvolvedores criem integrações mais robustas.

  • Ação necessária do desenvolvedor: ao criar o back-end, você precisa implementar a lógica para interceptar essas chaves, verificar tentativas anteriores e retornar a resposta armazenada em cache

"Upsert" (atualizar ou inserir) é uma operação de banco de dados idempotente clássica. Em vez de uma simples "inserção", um upsert diz: "Se este registro existir, atualize-o; caso contrário, crie-o".

  • Gerenciada para você: essa lógica é gerenciada de forma nativa pelo mecanismo de banco de dados, garantindo que os registros convirjam para o estado correto, independentemente de quantas vezes o script seja executado

Resolva seus desafios comerciais com o Google Cloud

Clientes novos recebem US$ 300 em créditos para usar no Google Cloud.
Fale com um especialista em vendas do Google Cloud para falar sobre soluções exclusivas.

Como criar microsserviços confiáveis no Google Cloud

O Google Cloud oferece várias ferramentas que facilitam a implementação desses padrões para os desenvolvedores. A criação em uma plataforma gerenciada reduz a quantidade de código "boilerplate" que você precisa escrever para manter seus dados seguros.

  • Cloud Run: ao usar o Cloud Run para processar eventos do Pub/Sub, lembre-se de que o Pub/Sub pode entregar mensagens mais de uma vez por padrão. Escrever código idempotente nos serviços do Cloud Run é um requisito para garantir que seus agentes de IA ou pipelines de dados não processem o mesmo evento duas vezes.
  • Observação sobre o Pub/Sub: embora a entrega padrão seja baseada em push, a entrega exatamente uma vez está disponível para assinaturas baseadas em pull. É útil conhecer esses dois tipos para escolher o nível certo de complexidade para seu serviço.

Tudo pronto para criar?

Saiba como implantar serviços resilientes e idempotentes no Cloud Run hoje mesmo.

Google Cloud