İçeriğe geç
Muhammet Şafak
en
Soran: Bora Cevaplandı:

Kısmi güncellemelerde JSON Merge Patch mı JSON Patch mı kullanmalıyım?


Soru

Laravel tabanlı bir REST API'miz var ve kaynak güncellemeleri `PUT` ile yapılıyor. İstemcinin her seferinde kaynağın tamamını göndermesi gerekiyor; sadece tek bir alanı değiştirmek isteyen mobil uygulama bile bütün objeyi geri yolluyor. Sorun şu: iki kullanıcı aynı profili neredeyse aynı anda düzenlediğinde, ikincinin `PUT`'u birincinin değiştirdiği alanları eski değerleriyle eziyor. Klasik lost update. Kısmi güncellemeye (`PATCH`) geçmeyi düşünüyorum ama JSON Merge Patch mı yoksa JSON Patch mı seçmeliyim, ikisinin farkı pratikte ne oluyor?

Cevap

Kısa cevap

Önce iki işi ayıralım — PATCH biçimini seçmek ayrı, lost update’i çözmek ayrı.

Bağlam

Biçim tarafında çoğu CRUD için JSON Merge Patch yeter; kayıp güncellemeyi ise biçim değil, koşullu istekler (ETag/If-Match) çözer.

Neden

  1. JSON Merge Patch (RFC 7396) basit ve durumların çoğunu karşılar. Media type’ı application/merge-patch+json. Sadece değiştirmek istediğiniz alanları gönderirsiniz, gerisine dokunmazsınız. İnsan tarafından okunması ve üretilmesi kolay; tipik “şu iki alanı güncelle” senaryosu için doğru araç.

  2. JSON Patch (RFC 6902) güçlü ama pahalı. Bir işlem dizisidir: add, remove, replace, move, copy, test. Dizinin belirli bir elemanına path ile dokunabilir, hatta test ile “şu değer hâlâ buysa uygula” diyebilirsiniz. Karşılığında istemci ve sunucu tarafında üretmesi, doğrulaması ve okunması belirgin biçimde daha zordur.

  3. Merge Patch’in iki tuzağını bilin. Birincisi: null “bu alanı sil” demektir, dolayısıyla bir alanı bilinçli olarak null’a çekmek ile silmek arasında ayrım yapamazsınız. İkincisi: diziler tümüyle değiştirilir, eleman bazlı patch yoktur. Bu iki ihtiyaç gerçekse JSON Patch’e geçmelisiniz.

Ne yapmalı

  1. Asıl sorun biçimle değil concurrency kontrolüyle çözülür. PATCH’e geçmek gövdeyi küçültür ama iki eşzamanlı yazmanın çakışmasını engellemez. Bunun için ETag + If-Match başlığı ya da bir version kolonu kullanın: istemci okuduğu ETag’i geri gönderir, sunucu değişmişse 412 Precondition Failed döner. JSON Patch’in test op’u da aynı işi görebilir ama HTTP katmanında ETag daha temizdir.

    # Sadece display_name'i güncelle, çakışmayı ETag ile koru
    curl -X PATCH https://api.example.com/users/42 \
      -H "Content-Type: application/merge-patch+json" \
      -H 'If-Match: "a1b2c3"' \
      -d '{"display_name": "Bora"}'
  2. Validation’ı kısmi gövdeye göre uyarlayın. Laravel’de PUT için tüm alanları required sayan kurallar PATCH’te işe yaramaz; sometimes ile “gelmişse doğrula” mantığına geçin, yoksa eksik alan hata verir.

Sonuç: Ben olsam varsayılan olarak Merge Patch + ETag/If-Match kurardım — bu ikisi hem gövdeyi küçültür hem lost update’i kökten keser. Diziye eleman bazlı dokunmam ya da atomik koşullu çok-alan işlemlerim gerçekten varsa, sadece o uçlarda JSON Patch’e geçerdim. Biçim seçimini tek başına lost update çözümü sanmayın; PATCH’i seçseniz bile koşullu istek yoksa aynı yarışı yaşarsınız.

Yorumlar

Yorum yapmak için GitHub hesabınızla giriş yapmanız yeterli. Yorumlar GitHub Discussions üzerinde saklanır.

Diğer Sorular

Tüm sorular

Sitede Ara

Yazı, proje ve sayfalarda arama yapmak için yazmaya başlayın.

Esc ile kapat Pagefind ile güçlendirildi