Compartilhar via


Usar o cabeçalho HTTP If-Match em operações PUT e PATCH

Para pontos de extremidade REST, os desenvolvedores geralmente querem controle sobre se as atualizações criam novos registros ou modificam apenas os existentes. O If-Match cabeçalho HTTP fornece esse controle no DAB (Construtor de API de Dados).

Por padrão, o DAB trata PUT e PATCH como operações upsert :

  • Se o recurso existir: ele será atualizado.

  • Se ele não existir: ele será inserido.

    • PUT → upsert completo (substitui o recurso).
    • PATCH → upsert incremental (aplica atualização parcial).

Adicionar If-Match: * alterações nesse comportamento à semântica somente de atualização.

O que If-Match faz no DAB

If-Match tem suporte apenas com o valor *curinga.

Valor do Cabeçalho Comportamento
If-Match: * Execute a atualização somente se o recurso existir; se o → 404 não foi encontrado.
If-Match: <any other> Indeferido; 400 Solicitação Inválida (Etags not supported, use '*').
(ausente) Comportamento upsert (inserir se não for encontrado, caso contrário, atualizar).

Visão geral do comportamento

  • O DAB não implementa a ETag por registro ou a correspondência de versão.
  • Nenhum token de simultaneidade é avaliado. * afirma apenas "deve existir".
  • Aplica-se somente ao REST, não ao GraphQL.
  • No momento, não é significativo para operações DELETE.

Usando If-Match com PUT

Sem If-Match, PUT insere quando o recurso não existe (retorna 201 Created).

Exemplo somente de atualização

Solicitação

PUT /api/Books/id/1
If-Match: *
Content-Type: application/json

{
  "title": "The Return of the King"
}

Sucesso (o registro existia)

HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 1,
  "title": "The Return of the King"
}

Falha (registro ausente)

HTTP/1.1 404 Not Found
Content-Type: application/json

{
  "error": "No Update could be performed, record not found"
}

Exemplo de inserção upsert (nenhum If-Match e registro não existia)

Solicitação

PUT /api/Books/id/500
Content-Type: application/json

{
  "title": "Inserted via PUT",
  "publisher_id": 7
}

Resposta

HTTP/1.1 201 Created
Location: id/500
Content-Type: application/json

{
  "id": 500,
  "title": "Inserted via PUT",
  "publisher_id": 7
}

Usando If-Match com PATCH

PATCH se comporta da mesma forma. Sem If-Match, ele executa um upsert incremental. Com If-Match: *, ele atualiza apenas as linhas existentes.

Solicitação

PATCH /api/Books/id/1
If-Match: *
Content-Type: application/json

{
  "title": "The Two Towers"
}

Resposta quando êxito

HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 1,
  "title": "The Two Towers"
}

Resposta quando não encontrado

HTTP/1.1 404 Not Found
Content-Type: application/json

{
  "error": "No Update could be performed, record not found"
}

Uso de If-Match inválido

Qualquer valor diferente * (incluindo cadeias de caracteres entre aspas) é rejeitado.

Solicitação

PUT /api/Books/id/1
If-Match: "abc123"
Content-Type: application/json

{
  "title": "To Kill a Mockingbird"
}

Resposta

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "error": "Etags not supported, use '*'"
}

Review

  • Omita If-Match a semântica upsert (insert-or-update).
  • Use If-Match: * para semântica somente atualização estrita (404 se o item estiver ausente).
  • Não use nenhum outro valor. A correspondência de ETag real não é implementada.