Idempotência
Uma requisição que contrata ou muda algo pode falhar no caminho de volta: tempo esgotado, conexão caída. Repetir sem cuidado pode contratar dois servidores ou cobrar duas vezes. O cabeçalho Idempotency-Key resolve isso: a mesma chave devolve a resposta da primeira requisição, sem fazer de novo.
Onde vale
Seção intitulada “Onde vale”Estes POST aceitam Idempotency-Key:
| Operação | |
|---|---|
| Contratar um servidor | POST /cloud/servers (gera cobrança) |
| Ligar, desligar ou reiniciar | POST /cloud/servers/{id}/power |
| Reinstalar | POST /cloud/servers/{id}/reinstall |
| Apagar o sistema | POST /cloud/servers/{id}/wipe |
| Cadastrar chave SSH | POST /cloud/ssh-keys |
| Contratar IP elástico | POST /cloud/network/elastic-ips (gera cobrança quando tem preço) |
| Mover IP elástico | POST /cloud/network/elastic-ips/{id}/assign |
| Criar rede privada | POST /cloud/network/private-networks |
| Colocar servidor na rede | POST /cloud/network/private-networks/{id}/servers |
Sem a chave, cada chamada aceita faz a operação: contratar duas vezes contrata duas máquinas.
Como usar
Seção intitulada “Como usar”Gere uma chave nova para cada operação (um UUID serve) e guarde-a junto com o que está fazendo. Se não souber se a primeira tentativa deu certo, repita a mesma chave com a mesma requisição:
KEY=$(uuidgen) # numa nova tentativa da mesma contratação, use a mesma KEYcurl -X POST https://dash.halver.com.br/api/v1/cloud/servers \ -H "Authorization: Bearer $HALVER_API_TOKEN" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: $KEY" \ -d '{"site_id":"…","plan_id":"…","os_image_id":"…","hostname":"web-01"}'As regras
Seção intitulada “As regras”- A chave: de 1 a 255 caracteres ASCII visíveis. Pode vir pura ou entre aspas, como string de Structured Field, no formato do rascunho da IETF (draft-ietf-httpapi-idempotency-key-header). Fora disso:
400 idempotency.invalid_key. - Validade: 24 horas, por conta e por credencial. Cada token tem as suas chaves: a mesma chave em dois tokens são duas chaves.
- Mesma chave, mesma requisição (método, caminho, parâmetros e corpo): a API devolve a resposta guardada, o mesmo status e o mesmo corpo, com o cabeçalho
Idempotent-Replayed: true. Nada é feito de novo. - Mesma chave, outra requisição:
422 idempotency.key_reused. Gere uma chave nova. - A primeira ainda roda:
409 idempotency.in_progresscomRetry-After. Espere e repita. - Toda resposta fica guardada, inclusive erros 5xx. Uma falha pode vir depois de a cobrança ou a operação já ter acontecido, e repetir não pode fazer de novo. Depois de um 5xx, confira o recurso com um
GETe, se precisar, tente com uma chave nova. - Só 401, 403, 409 e 429 liberam a chave, porque dizem que nada foi feito: depois de corrigir o token, o escopo ou esperar, repita com a mesma chave.
- Uma chave presa por uma requisição que morreu no meio (o processo caiu) é liberada depois de 10 minutos.
- Um pedido, um servidor, mesmo sem a chave: com
external_id(o id do seu pedido) no deploy, outro deploy com o mesmo valor, com outra chave ou sem chave, responde409 cloud.external_id_takencom o servidor existente emexisting_id. A repetição com a mesma chave continua devolvendo a resposta guardada. - O corpo da requisição nunca é guardado, só o hash dele: o
user_datae outros segredos não ficam na tabela de chaves.
Exemplo de repetição
Seção intitulada “Exemplo de repetição”HTTP/1.1 201 CreatedContent-Type: application/jsonIdempotent-Replayed: trueRetry-After: 10
{ "id": "307d7f63-0f00-4d4b-bc28-839d359e13a3", "hostname": "web-01", "status": "deploying", "operation_id": "38b54c25-…" }O Retry-After de uma resposta repetida é o da resposta original. Para saber como a operação está agora, consulte a operação (Operações assíncronas).