Bagikan melalui


Menggunakan Header HTTP If-Match dalam operasi PUT dan PATCH

Untuk titik akhir REST, pengembang sering menginginkan kontrol atas apakah pembaruan membuat rekaman baru atau hanya memodifikasi yang sudah ada. Header If-Match HTTP menyediakan kontrol tersebut di penyusun API Data (DAB).

Secara default, DAB memperlakukan PUT dan PATCH sebagai operasi upsert :

  • Jika sumber daya ada: sumber daya diperbarui.

  • Jika tidak ada: itu disisipkan.

    • PUT → upsert penuh (menggantikan sumber daya).
    • PATCH → upsert inkremental (menerapkan pembaruan parsial).

If-Match: * Menambahkan perubahan perilaku ini ke semantik khusus pembaruan.

Apa yang If-Match lakukan di DAB

If-Match hanya didukung dengan nilai *kartubebas .

Nilai Header Perilaku
If-Match: * Lakukan pembaruan hanya jika sumber daya ada; jika hilang → 404 Tidak Ditemukan.
If-Match: <any other> Ditolak; 400 Permintaan Buruk (Etags not supported, use '*').
(Tidak ada) Perilaku upsert (sisipkan jika tidak ditemukan, jika tidak, perbarui).

Gambaran umum perilaku

  • DAB tidak menerapkan ETag per rekaman atau pencocokan versi.
  • Tidak ada token konkurensi yang dievaluasi. * hanya menegaskan "harus ada."
  • Hanya berlaku untuk REST, bukan GraphQL.
  • Saat ini tidak bermakna untuk operasi DELETE.

Menggunakan If-Match dengan PUT

Tanpa If-Match, PUT menyisipkan ketika sumber daya tidak ada (mengembalikan 201 Created).

Contoh khusus pembaruan

Permohonan

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

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

Berhasil (rekaman ada)

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

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

Kegagalan (rekaman hilang)

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

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

Contoh sisipkan upsert (tidak ada If-Match dan rekaman yang tidak ada)

Permohonan

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

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

Jawaban

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

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

Menggunakan If-Match dengan PATCH

PATCH bertempur sama. Tanpa If-Match, ia melakukan upsert inkremental. Dengan If-Match: *, ini hanya memperbarui baris yang ada.

Permohonan

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

{
  "title": "The Two Towers"
}

Respons saat Berhasil

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

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

Respons ketika Tidak ditemukan

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

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

Penggunaan If-Match Tidak Valid

Nilai apa pun selain * (termasuk string yang dikutip) ditolak.

Permohonan

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

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

Jawaban

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

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

Tinjauan

  • Hilangkan If-Match untuk semantik upsert (insert-or-update).
  • Gunakan If-Match: * untuk semantik khusus pembaruan yang ketat (404 jika item hilang).
  • Jangan gunakan nilai lain. Pencocokan ETag nyata tidak diimplementasikan.