Method safety e idempotência
ResumoSafety e idempotência são propriedades dos métodos HTTP que guiam o design correto de uma API. Entendê-las evita efeitos colaterais inesperados e permite retries seguros.
1. Objetivos de Aprendizagem#
- Definir método seguro (safe) e método idempotente.
- Classificar GET, HEAD, PUT, DELETE, POST e PATCH.
- Aplicar essas propriedades ao projetar endpoints.
2. Pré-requisitos#
- Noções de verbos HTTP (Módulo 18).
3. Conceito#
- Seguro (safe): não altera o estado do servidor. Ex.:
GET,HEAD,OPTIONS. - Idempotente: executar N vezes tem o mesmo efeito de executar 1 vez. Ex.:
GET,PUT,DELETE.
O porquê: clientes, proxies e mecanismos de retry assumem essas propriedades. Um GET que apaga dados quebra a web; um PUT não idempotente causa duplicações em retries.
4. Mão na Massa#
4.1. Setup#
Conceitual — sem código novo. Vamos raciocinar sobre o design.
4.2. Implementação Passo a Passo#
Tabela de referência:
| Método | Seguro? | Idempotente? | Uso típico |
|---|---|---|---|
| GET | Sim | Sim | Ler recurso |
| HEAD | Sim | Sim | Metadados/headers |
| OPTIONS | Sim | Sim | Métodos suportados |
| PUT | Não | Sim | Substituir recurso |
| DELETE | Não | Sim | Remover recurso |
| POST | Não | Não | Criar recurso |
| PATCH | Não | Não (não garantido) | Atualização parcial |
Raciocínio-chave:
PUT /produtos/1com o mesmo corpo N vezes → mesmo estado final ⇒ idempotente.POST /produtosN vezes → N produtos criados ⇒ não idempotente.DELETE /produtos/1repetido → o recurso continua removido (o404subsequente é o comportamento esperado) ⇒ idempotente.
4.3. Executando#
Experimente chamar DELETE duas vezes no mesmo recurso e observe: a segunda chamada tipicamente retorna 404, mas o estado do servidor é o mesmo — o que caracteriza idempotência.
5. Exemplo Completo#
Design idempotente de criação com chave de idempotência (padrão avançado):
// Cliente envia um cabeçalho Idempotency-Key; o servidor guarda a resposta
// associada à chave e reusa em retries, tornando o POST efetivamente idempotente.
[HttpPost]
public async Task<IActionResult> Criar([FromHeader(Name = "Idempotency-Key")] string? key,
[FromBody] ProdutoForCreationDto dto)
{
// Se já processamos essa key, retornamos a resposta anterior.
// ... (armazenamento da chave omitido)
return CreatedAtRoute("ProdutoById", new { id = Guid.NewGuid() }, dto);
}
6. Boas Práticas e Armadilhas#
| Faça | Evite |
|---|---|
Manter GET sempre seguro (sem efeitos colaterais) | Alterar estado dentro de um GET |
Projetar PUT/DELETE como idempotentes | Fazer PUT gerar novos ids a cada chamada |
Usar chave de idempotência para POST crítico (pagamentos) | Ignorar retries e criar recursos duplicados |
Atençãoidempotência é sobre o efeito no estado, não sobre o status code retornado.
DELETErepetido retornar404não viola idempotência.
7. Segurança e Produção#
- Métodos seguros nunca devem exigir mudança de estado; caso contrário, caches e crawlers podem causar efeitos indesejados.
- Para operações financeiras, chaves de idempotência previnem cobranças duplicadas em retries de rede.
8. Exercícios#
- Fácil: classifique cada endpoint da sua API como seguro/idempotente.
- Médio: explique por que
PATCHnão é garantidamente idempotente. - Desafio: esboce um armazenamento de
Idempotency-Keycom expiração para endpoints de criação.
9. Resumo#
Safety e idempotência orientam o design HTTP: GET/HEAD são seguros; GET/PUT/DELETE são idempotentes; POST/PATCH não. Respeitar isso torna a API previsível e resiliente a retries.
10. Próximos Passos#
Módulo 23: criando recursos com POST, incluindo coleções e model binding.
11. Referências#
- MDN Web Docs — Métodos HTTP seguros e idempotentes
- Microsoft Learn — Diretrizes de design de APIs REST
- RFC 9110 — HTTP Semantics