Condividi tramite


Usare l'intestazione HTTP If-Match nelle operazioni PUT e PATCH

Per gli endpoint REST, gli sviluppatori spesso vogliono controllare se gli aggiornamenti creano nuovi record o modificano solo quelli esistenti. L'intestazione If-Match HTTP fornisce tale controllo in Generatore API dati (DAB).

Per impostazione predefinita, DAB considera PUT e PATCH come operazioni upsert :

  • Se la risorsa esiste, viene aggiornata.

  • Se non esiste, viene inserito.

    • PUT → upsert completo (sostituisce la risorsa).
    • PATCH → upsert incrementale (applica l'aggiornamento parziale).

Aggiunta di If-Match: * modifiche a questo comportamento per la semantica di sola aggiornamento.

Operazioni If-Match in DAB

If-Match è supportato solo con il valore *con caratteri jolly .

Valore intestazione Comportamento
If-Match: * Eseguire l'aggiornamento solo se la risorsa esiste; se manca → 404 Non trovato.
If-Match: <any other> Respinto; 400 Richiesta non valida (Etags not supported, use '*').
(assente) Comportamento upsert (inserimento se non trovato, in caso contrario aggiornamento).

Panoramica del comportamento

  • DAB non implementa la corrispondenza per record ETag o versione.
  • Non viene valutato alcun token di concorrenza. * solo asserzioni "deve esistere".
  • Si applica solo a REST, non a GraphQL.
  • Attualmente non significativo per le operazioni DELETE.

Uso di If-Match con PUT

Senza If-Match, PUT inserisce quando la risorsa non esiste (restituisce 201 Created).

Esempio di solo aggiornamento

Richiesta

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

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

Operazione riuscita (record esistente)

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

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

Errore (record mancante)

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

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

Esempio di inserimento upsert (nessun If-Match e record non esisteva)

Richiesta

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

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

Risposta

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

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

Uso di If-Match con PATCH

PATCH si comporta in modo analogo. Senza If-Match, esegue un upsert incrementale. Con If-Match: *, aggiorna solo le righe esistenti.

Richiesta

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

{
  "title": "The Two Towers"
}

Risposta in caso di esito positivo

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

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

Risposta quando non è stato trovato

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

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

Utilizzo If-Match non valido

Qualsiasi valore diverso da * (incluse le stringhe tra virgolette) viene rifiutato.

Richiesta

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

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

Risposta

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

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

Review

  • Omettere If-Match la semantica upsert (insert-or-update).
  • Usare If-Match: * per una semantica rigorosa di sola aggiornamento (404 se l'elemento non è presente).
  • Non usare altri valori. La corrispondenza ETag reale non viene implementata.