Home Comunidade Eventos YouTube Networks Desafios // produtos Academy News CTI | CVE Contato

03 - PUT - Atualiza Recurso

video explicativo
Video explicativoEspaco reservado para o video desta anotação — adicione video: https://youtu.be/... no frontmatter da nota.

PUT - Atualiza Recurso

1. Definição e Semântica

O método HTTP PUT é definido pela RFC 7231 (seção 4.3.4) como o método que solicita a criação ou substituição completa do estado do recurso identificado pela URL alvo. Sua semântica é de "store" (armazenar): o servidor deve guardar o corpo da requisição como representação canônica do recurso naquela URL.

Características Formais

  • Método: PUT
  • Seguro: Não (modifica estado do servidor)
  • Idempotente: Sim (múltiplas execuções produzem o mesmo estado)
  • Cacheável: Não (por padrão; apenas se houver header Content-Location explícito)
  • Corpo na requisição: Sim, obrigatório (representação completa do recurso)
  • Corpo na resposta: Opcional
  • RFC de referência: RFC 7231 (HTTP/1.1 Semantics), RFC 9110 (HTTP Semantics, obsoleta a 7231)

Idempotência

A idempotência é a propriedade central do PUT. Se o cliente enviar a mesma requisição PUT 1, 10 ou 1000 vezes, o estado final do recurso deve ser idêntico. Isso difere do POST, onde múltiplas execuções podem criar múltiplos recursos (ex: múltiplas ordens de compra).

PUT /users/42 HTTP/1.1
Host: api.exemplo.com
Content-Type: application/json
Authorization: Bearer eyJ...

{"id": 42, "name": "Alice", "email": "alice@exemplo.com", "age": 30}

Se a requisição acima for retransmitida pelo cliente (ex: timeout), o resultado final será o mesmo: o recurso /users/42 conterá exatamente os campos enviados.

2. Criação vs Atualização

O PUT pode ser usado tanto para criar quanto para atualizar um recurso, desde que o cliente controle a URL alvo. Isso é diferente do POST, em que tipicamente o servidor gera a URL (ex: POST /users retorna 201 Created com Location: /users/42).

Criação com PUT

PUT /users/42 HTTP/1.1
Content-Type: application/json

{"name": "Alice", "email": "alice@exemplo.com"}

Resposta: 201 Created se o recurso não existia; 200 OK ou 204 No Content se já existia e foi substituído.

Atualização com PUT

A semântica é de substituição completa. Se o recurso existia com 5 campos e o PUT envia apenas 2, o resultado é um recurso com apenas esses 2 campos — os demais são removidos.

Estado inicial:    {"id":42, "name":"Alice", "email":"alice@x.com", "age":30, "city":"SP"}
PUT enviado:       {"id":42, "name":"Alice Silva"}
Estado final:      {"id":42, "name":"Alice Silva"}

Esta é a principal diferença em relação ao PATCH, que faz atualização parcial preservando campos não enviados.

3. PUT vs POST vs PATCH

Critério POST PUT PATCH
Semântica Criar/ação genérica Substituir recurso Atualização parcial
Idempotente Não Sim Não (por padrão)
Cliente define URL Geralmente não Sim Sim
Corpo completo Sim, para criação Sim, obrigatório Não, apenas deltas
RFC 7231 §4.3.3 7231 §4.3.4 5789

Exemplo Comparativo

Recurso: {"id":1, "name":"Bob", "email":"bob@x.com"}

  • POST /users/1 — não usual (POST é para criar novo, não operar sobre existente).
  • PUT /users/1 com {"name":"Robert"} — resultado: {"name":"Robert"} (email removido).
  • PATCH /users/1 com {"name":"Robert"} — resultado: {"id":1, "name":"Robert", "email":"bob@x.com"}.

4. Headers Importantes

Content-Type

Indica o formato do corpo enviado. Para APIs REST modernas, application/json é padrão. Outros comuns: application/xml, application/x-www-form-urlencoded, text/plain.

Content-Length

Obrigatório quando o corpo é enviado de uma vez. Para uploads chunked, usa-se Transfer-Encoding: chunked.

If-Match (Controle de Concorrência)

Implementa optimistic locking via ETag. O servidor só aplica o PUT se a ETag do recurso atual casar com a informada; caso contrário, retorna 412 Precondition Failed.

PUT /users/42 HTTP/1.1
If-Match: "abc123"
Content-Type: application/json

{"name":"Alice 2.0"}

Expect: 100-continue

Cliente anuncia que tem um corpo grande para enviar e aguarda o servidor concordar antes de transmitir. Evita desperdiçar banda em uploads que seriam rejeitados (ex: arquivo muito grande).

5. Códigos de Resposta Típicos

Status Significado Quando
200 OK Sucesso com corpo Atualização bem-sucedida, retorna recurso
201 Created Recurso criado PUT criou novo recurso na URL
204 No Content Sucesso sem corpo Atualização bem-sucedida, sem payload de retorno
400 Bad Request Sintaxe inválida JSON malformado, campos obrigatórios faltando
401 Unauthorized Falta autenticação Token ausente ou inválido
403 Forbidden Sem permissão Autenticado, mas sem direito de escrita
404 Not Found Recurso não existe PUT em coleção inexistente
409 Conflict Conflito de estado Versão/ETag incompatível, locks
412 Precondition Failed If-Match falhou ETag não corresponde
415 Unsupported Media Type Content-Type não suportado Servidor só aceita JSON, recebeu XML

6. Exemplos Práticos

curl — Atualizar Usuário

curl -X PUT https://api.exemplo.com/users/42 \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"name":"Alice Silva","email":"alice.silva@exemplo.com"}'

curl — Criar Recurso com PUT (Upsert)

curl -X PUT https://api.exemplo.com/articles/tech-http-put \
  -H "Content-Type: application/json" \
  -d '{"title":"Entendendo PUT","author":"Alice"}'

Python (requests)

import requests
r = requests.put(
    "https://api.exemplo.com/users/42",
    json={"name": "Alice Silva", "email": "alice.silva@exemplo.com"},
    headers={"Authorization": "Bearer " + token},
)
print(r.status_code, r.json())

7. Boas Práticas em APIs REST

Versionamento de Recurso

Inclua a versão na URL ou no header (Accept: application/vnd.api+json;version=1):

PUT /v1/users/42

Validação de Schema

Valide o corpo antes de persistir. Use JSON Schema (draft 2020-12) para definir o formato esperado do payload.

Retorno Padronizado

Retorne o recurso atualizado em respostas 200 OK para que o cliente confirme o estado persistido. Para 204 No Content, o cliente precisa confiar no sucesso silencioso.

Controle de Concorrência

Sempre implemente ETag + If-Match em recursos editáveis por múltiplos clientes. Isso evita "lost updates" quando dois usuários editam o mesmo recurso simultaneamente.

Idempotência na Prática

Se o servidor usa um identificador de requisição (Idempotency-Key), guarde o resultado por algumas horas. Retornar a mesma resposta para a mesma chave evita duplicações acidentais em retries.

8. Erros Comuns

Erro Causa Correção
Substituição perde campos PUT enviado com payload parcial Usar PATCH para atualização parcial
Criação acidental PUT em URL inexistente cria recurso Validar existência antes, ou usar POST para criar
Duplicação em retries Falta de Idempotency-Key Gerar UUID por requisição e validar no servidor
415 Unsupported Media Type Content-Type incompatível Padronizar JSON na API

9. Resumo Técnico

Atributo Valor
Método PUT
RFC 7231 §4.3.4 (obsoleta por 9110)
Idempotente Sim
Seguro Não
Cacheável Não (sem Content-Location)
Corpo obrigatório Sim
Sucessos típicos 200, 201, 204
Concorrência ETag + If-Match

10. Conclusão

O método PUT é o mecanismo HTTP para substituição idempotente de recursos. Sua característica de idempotência o torna seguro para retries em redes instáveis, mas sua semântica de substituição completa exige que o cliente envie o estado integral do recurso. Em APIs REST modernas, PUT coexiste com PATCH (para atualizações parciais) e POST (para criação não idempotente). O uso correto de headers como If-Match e Idempotency-Key é essencial para garantir consistência em ambientes distribuídos com múltiplos clientes concorrentes.