Idempotência HTTP: o que é, como funciona e por que importa
Idempotência HTTP garante que repetir uma requisição não altera o resultado final. Veja quais métodos são idempotentes, como funciona na prática e por que isso evita bugs em APIs.
Idempotência HTTP garante que repetir uma requisição não altera o resultado final. Veja quais métodos são idempotentes, como funciona na prática e por que isso evita bugs em APIs.
Idempotência HTTP é a propriedade que garante que executar a mesma requisição várias vezes produz o mesmo resultado final que executá-la uma única vez. Na prática, se você enviar a mesma chamada HTTP duas, três ou dez vezes, o efeito no servidor será o mesmo de uma chamada só. Isso é fundamental para evitar bugs em APIs, principalmente quando há falhas de rede, timeouts ou retentativas automáticas.
O conceito vem da matemática, onde uma operação é idempotente se aplicar várias vezes não muda o resultado. Multiplicar um número por zero é idempotente: 5 × 0 = 0, e 5 × 0 × 0 também é 0. No HTTP, a lógica é parecida, mas aplicada a requisições e respostas.
Quais métodos HTTP são idempotentes?
Os métodos idempotentes do protocolo HTTP são:
- GET: busca um recurso. Repetir a requisição não altera nada no servidor.
- PUT: atualiza ou cria um recurso com base no payload. Enviar o mesmo PUT duas vezes deixa o recurso no mesmo estado.
- DELETE: remove um recurso. Apagar algo que já foi apagado não tem efeito adicional.
- HEAD: igual ao GET, mas retorna apenas os cabeçalhos. Também é idempotente.
- OPTIONS: consulta as opções de comunicação. Repetir não muda estado.
- TRACE: ecoa a requisição para diagnóstico. Idempotente por natureza.
Métodos como POST e PATCH não são idempotentes. O POST cria um novo recurso a cada chamada, então repetir a requisição gera múltiplos registros. O PATCH aplica uma modificação parcial, e o resultado pode variar dependendo do estado atual do recurso.
Como a idempotência funciona na prática?
Imagine que você está pagando uma fatura via API. Se a resposta da requisição se perde na rede e o cliente reenvia o POST, o servidor pode processar o pagamento duas vezes. Com idempotência, o servidor reconhece que a requisição é a mesma e retorna a resposta anterior, sem cobrar de novo.
Para implementar isso, muitas APIs usam uma chave de idempotência: um identificador único enviado pelo cliente no cabeçalho da requisição. O servidor armazena essa chave junto com a resposta. Se a mesma chave chegar novamente, ele devolve a resposta salva, em vez de processar de novo.
Um exemplo real: a API do Stripe exige que você envie um cabeçalho Idempotency-Key em requisições que criam cobranças. Se a conexão cair, você reenvia a mesma chave e o Stripe garante que a cobrança só será criada uma vez.
Por que idempotência HTTP importa para APIs?
Sem idempotência, qualquer retentativa automática pode causar efeitos colaterais indesejados. Um GET duplicado é inofensivo, mas um POST duplicado pode criar registros repetidos, cobrar duas vezes ou enviar e-mails em dobro.
Em sistemas distribuídos, falhas de rede são comuns. Clientes costumam reenviar requisições quando não recebem resposta em tempo hábil. Se o método não for idempotente, o reenvio pode ser catastrófico.
A idempotência também simplifica a lógica do cliente. Em vez de o cliente precisar saber se a requisição anterior foi processada, ele pode simplesmente repetir a chamada com segurança. Isso reduz a complexidade do código e melhora a confiabilidade.
Qual a diferença entre idempotência e segurança?
Segurança no HTTP significa que o método não altera o estado do servidor. GET, HEAD, OPTIONS e TRACE são seguros. Idempotência, por outro lado, significa que repetir a requisição não muda o resultado final, mesmo que o método altere o estado.
Um método pode ser seguro e idempotente, como o GET. Pode ser não seguro e idempotente, como o DELETE. E pode ser não seguro e não idempotente, como o POST. Entender essa distinção ajuda a escolher o método certo para cada operação.
Na prática, um método seguro é sempre idempotente, mas o contrário não é verdadeiro. DELETE, por exemplo, altera o estado (remove um recurso), mas é idempotente porque apagar algo já removido não gera efeito novo.
Idempotência é garantida pelo protocolo ou pelo servidor?
O protocolo HTTP define quais métodos devem ser idempotentes, mas a implementação depende do servidor. Se um desenvolvedor criar um endpoint GET que incrementa um contador, ele está violando a especificação. O mesmo vale para um DELETE que retorna erro quando o recurso não existe, em vez de retornar 200 ou 204.
A idempotência é uma propriedade do comportamento do servidor, não apenas do método. O protocolo estabelece a intenção, mas o servidor precisa respeitá-la. Por isso, ao projetar uma API, é essencial garantir que os endpoints idempotentes realmente se comportem como tal.
Um caso comum de violação: um PUT que retorna erro se o recurso não existir, em vez de criá-lo. Isso quebra a idempotência, porque a primeira chamada falha e a segunda, após criação manual, funciona. O comportamento correto seria o PUT sempre criar ou atualizar o recurso, independentemente de existir antes.
Como testar se um método é idempotente?
A forma mais direta é enviar a mesma requisição duas vezes e comparar os efeitos. Para um GET, o estado do servidor deve ser idêntico após cada chamada. Para um PUT, o recurso deve terminar no mesmo estado, independentemente de quantas vezes você enviar.
Ferramentas como cURL ou Postman facilitam esse teste. Envie uma requisição, observe a resposta, envie novamente e confira se o resultado é o mesmo. Se houver qualquer diferença no estado do servidor, o método não está sendo tratado como idempotente.
Um teste mais avançado envolve simular falhas de rede e retentativas. Isso pode ser feito com proxies como o mitmproxy ou com testes de integração que forçam timeouts. O objetivo é garantir que o cliente possa reenviar a requisição sem medo de duplicar efeitos.
Idempotência e cache: qual a relação?
O cache HTTP aproveita a idempotência para armazenar respostas. Como GET e HEAD são idempotentes e seguros, suas respostas podem ser cacheadas por proxies e navegadores. Isso reduz a carga no servidor e melhora a latência.
Métodos não idempotentes, como POST, geralmente não são cacheados, porque repetir a requisição pode gerar efeitos diferentes. Porém, alguns frameworks permitem cache de respostas POST quando há uma chave de idempotência, desde que o servidor garanta o mesmo resultado para a mesma chave.
Na prática, o cache é uma otimização que depende da idempotência. Sem ela, não seria seguro reutilizar respostas antigas, pois o estado do servidor poderia mudar entre requisições.
Resumo
Idempotência HTTP é a garantia de que repetir uma requisição não altera o resultado final. Métodos como GET, PUT, DELETE e HEAD são idempotentes por definição, enquanto POST e PATCH não são. Implementar idempotência no servidor evita duplicações, simplifica retentativas e aumenta a confiabilidade de APIs.
FAQ
O que é idempotência HTTP?
Idempotência HTTP é a propriedade de um método que permite executar a mesma requisição várias vezes sem que o resultado final seja diferente de uma única execução. Ou seja, repetir a chamada não causa efeitos adicionais no servidor.
Quais métodos HTTP são idempotentes?
GET, PUT, DELETE, HEAD, OPTIONS e TRACE são idempotentes. POST e PATCH não são, porque POST cria um novo recurso a cada chamada e PATCH aplica modificações parciais que podem variar conforme o estado atual.
Por que idempotência é importante em APIs?
Porque evita efeitos duplicados quando há retentativas automáticas. Se um cliente reenvia uma requisição por causa de timeout, um método idempotente garante que o servidor não processe a mesma operação duas vezes, evitando cobranças duplicadas ou registros repetidos.
Qual a diferença entre idempotente e seguro?
Seguro significa que o método não altera o estado do servidor, como GET. Idempotente significa que repetir a requisição não muda o resultado final, mesmo que o método altere o estado, como DELETE. Todo método seguro é idempotente, mas nem todo idempotente é seguro.
Como implementar idempotência em uma API?
Use uma chave de idempotência, como um cabeçalho Idempotency-Key, que o cliente envia junto com a requisição. O servidor armazena a chave e a resposta correspondente. Se a mesma chave chegar novamente, ele retorna a resposta salva sem reprocessar.
O que acontece se um método não idempotente for repetido?
Pode gerar efeitos indesejados, como múltiplos registros, cobranças duplicadas ou alterações inconsistentes. Por isso, é essencial que o cliente evite reenviar requisições não idempotentes sem controle, ou que o servidor implemente mecanismos de idempotência.