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: DAB lo aggiorna.

  • Se non esiste: DAB lo inserisce.

    • 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

Importante

Poiché PUT esegue una sostituzione completa, il corpo della richiesta deve includere tutte le colonne non nullable. L'omissione di una colonna obbligatoria causa un 400 Bad Request errore del database, anche quando If-Match: * è presente. Usare PATCH invece di PUT se si desidera inviare solo un subset di campi.

Richiedi

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

{
  "title": "The Return of the King",
  "publisher_id": 7
}

Operazione riuscita (record esistente)

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

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

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)

Richiedi

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.

Richiedi

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.

Richiedi

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.

Annotazioni

La funzionalità Generatore API dati 2.0 descritta in questa sezione è attualmente in anteprima e potrebbe cambiare prima della disponibilità generale. Per altre informazioni, vedere Novità della versione 2.0.