ASP.NET Core Web API Uygulamasında HttpPatch işlemi

türkay ürkmez
4 min readAug 5, 2020

Bu hayatı, istesek de istemesek de dinamik bir biçimde yaşıyoruz. Hemen hiçbir şey aynı kalmıyor. Özellikle, yaşam alanımızdaki birçok varlığı zaman içinde güncelliyor, tamamen yeniliyoruz.

Örneğin, oturma odanızdaki koltuklarınız bir süre sonra işlevsiz bir hale geldiğinde (ya da canınız sıkıldığında) onları yenileme ihtiyacı duyuyorsunuz. Ya da kim bilir belki de evinize yeni bir oda eklemeyi bile planlıyor olabilirsiniz.

Yazılım uygulamalarında kullandığımız varlıklarda da durum aynı. Elbette, onları da güncellemeye açık bir biçimde yönetebilmemiz gerekiyor. Fakat kendi hayatımızdaki bir varlığı topyekün yenilemenin masraflı olması gibi, yazılımsal bir varlığı da tamamen güncellemek maliyetli olabiliyor.

Bu maliyeti indirgemek için gerçek hayatta ne yapıyoruz? Komple bir yenileme yerine, sadece belli bir özelliği değiştiriyoruz. Örneğin eski koltuk takımını tamamen çıkarıp yerine yenisini almaktansa, sadece kumaşını değiştirme şansına sahibiz.

Peki, bir RESTFul servis mimarisinde böyle bir yapı uygulayabilir miyiz?

Normal şartlarda bir Web API uygulamasında, sunucudaki bir varlığın güncellenmesi için istemciden o varlığın tüm özelliklerini isteriz. Sonra da söz konusu güncellemeyi yapar ve istemciye “200” yanıtını döndürürüz.

Projeye Başlıyoruz!

Elbette bu noktada kod tarafına geçip, biraz daha elle tutulur bir örnek üzerinden yürümek daha şık olacak. Bir .NET Core 3.1 Web API projesi altında şu modelleri oluşturarak işe başlayalım.

Tabii yine de kodu temiz tutmak amacıyla, aşağıdaki Fake koleksiyonu tanımladım:

Elbette, bu In-Memory koleksiyon üzerinde işlem yapmak için bir de Service sınıfına ihtiyacım olacak.

Dediğim gibi, konuyu bağlamından uzaklaştırmamak adına servis içine insert operasyonunu eklemedim. Burada önceliğimiz sadece, güncelleme işlemine odaklanmak.

Pekala, böyle bir durumda API istemcisinin güncelleme yapmasını istiyorsak, nasıl bir metot yazacağız? Akla gelen en geleneksel metot, elbette http PUT metodu olacaktır.

O halde, TeamsController isimli API Controller sınıfımı aşağıdaki biçimde oluşturuyorum:

PUT’un neyi eksik canım?

Peki. İşte kritik bir noktadayız. Burada yer alan http PUT metodunun Team nesnesinin bir örneğini (instance) parametre olarak aldığına dikkat edelim. Bu ne demek? İstemci, bu eylemi çalıştırmak istiyorsa; Team varlığının TAMAMINI request içerisinde göndermek zorunda. Yani bu durumda, request içerisinde yer alan JSON verisi aşağıdaki gibi olmalı:

(url: https://localhost:44315/api/teams/1)

İyi ama, ben sadece Domagoj Vida’nın ülkesini güncellemek istiyorsam? Yani tek istediğim Team varlığının Players koleksiyonu içinde yer alan ikinci nesnenin “nationality” özelliğini Hırvatistan olarak değiştirmekse? Ama bunun için bütün Team varlığını oluşturup sunucuya göndermem gerekiyor!

Yani koltuğun sadece kılıfını değiştirebilecekken, tamamını yeniden sipariş vermem gibi bir şey bu!

İşte PATCH burada imdadımıza yetişiyor.

HttpPatch operasyonu

Şekildeki gibi bir JSON kaynağının belirli bir kısmını değiştirmek (ya da eklemek) istiyorsam, HttpPatch operasyonunu kullanıyoruz.

Dilerseniz ilk olarak, bu amaçla yazılmış bir PATCH Http request’in JSON içeriğine bakalım:

Şu kibarlığa bir bakın hele! Sadece ne iş yapacağını (“op”), nereye müdahale edeceğini, (“path”) ve veriyi (tabii ki “value”) söylememiz yeterli. Daha düşük karmaşıklık, hayat kurtarır.

Buradan anlayacağınız gibi PATCH sadece bir veriyi bir başkasıyla değiştirmek (replace) için kullanılmıyor. Başka operasyonları da var. Tamamı şöyle; “ add”, “ remove”, “ replace”, “ move”, “ copy” ve “ test “.

Peki, bu request türünü ASP.NET Core Web API içerisinde nasıl kullanacağız?

İlk olarak projemize,

Microsoft.AspNetCore.Mvc.NewtonsoftJson

Nuget paketini eklememiz gerekiyor. Sonra da projemizin Startup sınıfında bulunan ConfigureServices metodunda, AddNewtonsoftJson() extension metodunu çağırıyoruz:

DİKKAT!

Bu metodu çağırdığınızda, projenizde kullandığınız tüm JSON içeriğinin formatını ezmiş olursunuz (normalde System.Text.Json kütüphanesi kullanılır).

Artık JSON Patch için gerekli Action metodumuzu oluşturabiliriz.

http PATCH eylemi için Action metodu

Yukarıda gördüğünüz action metodunun olmazsa olmazlarına bakalım dilerseniz.

  1. [HttpPatch(“{id}”)] Attribute’ü ile işaretlenmiş durumda (eh bu normal tabii)
  2. Metod, JsonPatchDocument<Team> nesnesi alıyor! İşte bu önemli. Yukarıda örneğini gördüğümüz bir JSON Patch request’i içerisindeki komutları yorumlayan taşıyıcı nesnemiz, JsonPatchDocument<> nesnesi. Tahmin edebileceğiniz gibi request ile gelen talebin hangi varlığa (bizim örneğimizde Team) uygulanması gerektiğini jenerik olarak belirtiyoruz.
  3. patchDocument.ApplyTo(team,ModelState); metoduyla değişikliği uygulamasını söylüyoruz. Buradaki ModelState parametresi üzerinde biraz duralım. Ya PATCH içindeki komutun uygulanması sırasında bir hata oluşursa? Böyle bir durumda ASP.NET MVC’nin alametifarikalarından biri olan ModelState nesnesine hatayı yazdırmak iyi olurdu değil mi? İşte o ikinci parametre tam olarak bunu yapıyor.

O zaman Postman aracılığıyla talebimizi gönderelim bakalım.

Giden Talep:

Ve dönen yanıt:

Önceden de belirttiğim gibi, JSON PATCH ile başka operasyonlar da yapılabilir. Örneğin gelin yeni bir futbolcu ekleyelim:

Ya da JSON kaynağı içerisinde, silme, kopyalama ve taşıma işlemleri yapabilirsiniz. Bunları size bırakıyorum.

Fakat benim en başarılı bulduğum operasyon “ test” operasyonu. Diyelim ki, JSON kaynağımızda koşullu bir değişiklik yapmak istiyoruz. Örneğin “takımın ilk oyuncusunun adı Utku Yuvakuran ise pozisyonunu stoper olarak değiştir” demek istiyoruz. İşte o zaman şöyle yazıyoruz:

Eğer kaynaktaki adreste (“players/0/name”) bulunan değer Utku Yuvakuran değilse, değiştirme işlemini yapmayacaktır, çünkü testten geçememiş olacak. Böylece, hatalı bir değişiklik yapma ihtimalinizi en aza indirmiş oluyorsunuz!

Evet sevgili dostlar! Böylece, bir yazımızın daha sonuna gelmiş olduk. Elbette konu hakkındaki yorumlarınızı bekliyorum. Tabii bu arada eğer bu içeriği beğendiyseniz beni takip listenize ekleyebilirsiniz.

Hah neredeyse unutuyordum. Projenin kaynak kodları elbette burada:

https://github.com/turkayurkmez/PatchOperations/

Kendinize iyi bakın!

Orjinal yayın adresi: https://www.turkayurkmez.com (5 Ağustos 2020)

--

--

türkay ürkmez

Düşünen, düşündüğünü yazan, yazılım eğitimleri veren adam…