Günümüzde artık internet dünyası sadece kişisel bilgisayarlarda internet tarayıcıları tarafından görüntülenebilen web sitelerinden oluşmuyor. Mobil cihazlar, Televizyonlar, Akıllı Evler Aletleri v.b gibi birçok cihaz artık internet aleminde kaynak tüketimine dahil olmuş durumdadır. Şüphesiz bu giderek daha da genişleyecek. Bu çeşitlilik karşısında artık internet dünyasına sunulan bilgilerin nasıl temsil edildiği öne çıkmıştır. Örneğin bir cihaz JSON veri tipiyle işlem yaparken diğeri XML veri tipini tercih ediyor olabilir. HTTP üzerinden kaynak tüketimi göz önüne alındığında verilerin temsili(representation) content negotaition kavramı ile bütünleşiyor.
Bir önceki yazıda HTTP protokolüne özel bir kavram olan Content Negotiation kavramından genel olarak bahsetmiştik. Bu yazıda ise content negotiation konusunu Asp.Net Web api tarafından incelemeye çalışacağız.
Asp.net Web Api teknolojisi Content Negotiation ile uyumlu çalışmaktadır. Ancak bu kavram Web Api teknolojisinin bir parçası gibi anlaşılmamalıdır. Content Negotation kavramı W3C(World Wide Web Consortium) tarafından tanımlanmış bir internet içerik standartıdır. RFC(Request For Comment) döküman numarası 2616‘dır.
Content Negotiation kavramı Asp.net Web Api tarafında, kullanıcıların talebine göre verinin hangi biçimde sunulacağını belirlemek için kullanılan sunucu odaklı bir çözüm yöntemi olarak kullanılmaktadır. Kullanıcılar talep ettikleri ortam döküman türlerini HTTP header bilgisi olarak belirleyebilirler. Talepteki Header bilgisi Web Api tarafından değerlendirilerek uygun şekilde bir cevap oluşturulur ve HTTP protokolü üzerinden kullanıcıya sunulur.
Web Api bir kullanıcının hangi niyetle kaynak talep ettiğini anlamak için talebin(HttpRequest) Header bilgilerini kontrol eder. Header bilgilerinde içerik ile ilgili kısımlar şu şekilde sıralanabilir:
- Content-Type: API Burada belirtilen formatta veri sunar.
- Accept: Kullanıcı burada kabul ettiği veri türlerini belirtir. (application/json gibi)
- Accept-Charset:Kabul edilen karakter kodlaması. (UTF-8 gibi)
- Accept-Language: Kabul edilen dil seçeneği. (en-us, tr-tr gibi)
- Accept-Encoding:Kabul edilen içerik kodlaması. (gzip gibi)
Web Api uygulamasına Fiddlr gibi bir araç yardımıyla sorgulamalar yaparak durumu inceleyebiliriz.
Örneğin http://localhost:15063/api/values için bir talep gönderdiğimizde,
Web Api için oluşturulan talepte içerik bilgisine ait bir bildirim yapılmadı. Ancak sonucun JSON formatında geldiğini gözlemliyoruz. Bunun sebebi Web Api uygulamasının varsayılan olarak JSON formatında veri oluşturmasıdır.
Şimdi içerik talebini JSON değilde XML şeklinde istemeyi deneyelim. Bu durumda Content-Type: application/xml şeklinde bir Header bildirimi yapmamız gerekmektedir.
Dikat edecek olursak aynı URI üzerinden aynı kaynağa eriştiğimiz halde dönen cevap XML formatı şeklinde oldu. Yani kaynağın temsil ediliş şeklini HTTP Content Negotiation ile değiştirmiş olduk.
Farklı formatlarda veri alma talebini bir MVC uygulaması veya Web Froms ile yapmış olsaydık ya farklı URI üzerinden (sayfa veya action metod) oluşturacaktık, ya da aynı URI adresine parametre olarak kaynak türünü xml şeklinde belirtmiş olmamız gerekebilirdi.
Kullanıcılar Web Api uygulamalarına hangi türde veri kabul ettiklerini Accept header bilgisi ile bildirirler. Örneğin üç farklı formatta veri kabul ettiğimizi bildirecek olursak: Accept: application/xml, application/json, text/javascript
Bu durumda varsayılan değer olan JSON formatı şeklinde veri döner. application/json seçeneğini kaldırırsak bu sefer de XML veri döner.
Web Api tarafında medya tiplerine göre uygun içerik üretmek için Media Type Formatter sınıfları oluşturulur ve akışa dahil edilir. Eğer JSON veya XML gibi türler dışında kendi özel türümüzü oluşturmak istiyorsak System.Net.Http.Formatting.MediaTypeFormatter sınıfından türeteceğimiz sınıflarda istediğimiz veri formatlarını oluşturabiliriz.
XML sonucu alıp kullanan var mı acaba hala. Bence JSON in XML out.
Web Api ile haşır neşir olmuş biri olarak hiç bu açıdan bakmak aklıma gelmemişti. Bunu anlattığınız çok iyi oldu. Ben bir action metoda parametre göndererek sonuç almayı düşünmüştüm. Teşekkürler
Faydası olduğuna sevindim.