Pular para o conteúdo

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.

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.

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:

Janela do terminal
KEY=$(uuidgen) # numa nova tentativa da mesma contratação, use a mesma KEY
curl -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"}'
  • 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_progress com Retry-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 GET e, 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, responde 409 cloud.external_id_taken com o servidor existente em existing_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_data e outros segredos não ficam na tabela de chaves.
HTTP/1.1 201 Created
Content-Type: application/json
Idempotent-Replayed: true
Retry-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).