ASP.NET WEB API Hakkında Bir Çok Şey

ASP.NET Web Api Nedir ?

  • Api (Aplication Programming Interface), yani uygulama geliştirme arayüzü, sahip olduğumuz verileri belirli kurallar dahilinde dış platformlara açmamızı sağlayan arayüzdür. (Mobil, Tablet, PC ve bir çok HTTP destekli platform)
  • HTTP Protokolü üzerinden haberleşir. Tarayıcıya bir adres girdiğinizde esasen GET işlemi yaparsınız. Benzer şekilde forma veri girip gönderdiğinizde POST etmiş olursunuz. Apimiz buna benzer şekilde GET,POST,PUT,DELETE işlemlerini gerçekleştirir.
  • MVC tasarım kalıbına uygun olarak geliştirilmiştir.
  • Routing,Controllers,Action Result, Filter, Model Binders gibi MVC özelliklerini kullanabilirsiniz.
  • Internet Media Type olarak XML, JSON ve Custom formatları destekler.
  • WCF değildir. Windows Communication Foundation değildir fakat WCF içinde HTTP protokolünü destekleyen bir mimari mevcuttur. Bu mimari daha sonra geliştirilerek Web Api olarak karşımıza çıkmıştır.
  • REST mimarisi içerir. REST mimarisi ile geliştirilen servislere RESTful servisler denir. Web Api bir bakıma RESTful servis yazmaktır. (Representational State Transer- Temsili Durum Transferi, Apilerin neden temsili olduğu metnin devamındadır.)

 

HTTP Protokolü ve Web Api

HTTP- Hyper Text Transfer Protocol esasen webde uyulması gereken kurallardır. HTTP GET (READ),POST (CREATE),PUT (UPDATE), DELETE işlemlerini destekler. Web Api de HTTP gibi aynı kurallar üstünde işlem görmektedir. Tarayıcıya bir URL yazıp çağırdığınızda GET isteği (Request) yapmış olursunuz ve sunucu sayfayı açtığında arka planda size 200 kodlu bir response döner. Bu yazdığınız URL'nin doğru olduğunu gösterir ve sayfa içeriği browserınızda gösterilir.

HTTP Durum Kodları, yapılan istek neticesinde cevap olarak mutlaka dönmektedir.

  • 100'lü kodlar açıklama (Örn: 102 Processing)
  • 200'lü kodlar başarılı (Örn: 200 Başarılı)
  • 300'lü kodlar yönlendirme (Örn: 305 Use Proxy)
  • 400'lü kodlar istemci hataları (Örn: 404 Not Found)
  • 500'lü kodlar sunucu hatalarını ifade eder. (Örn: 500 Internal Server Error)

İnternetten tüm kodları bulabilirsiniz.

HTTP Header, Body Kavramı

Tarayıcı olarak ne kullanırsanız kullanının bir okuma (GET) işlemi yaptığınızda tarayıcıya (Mozilla,Opera,Chrome, Internet Explorer vs.) bir header bilgisi gönderilir. Siz bunu farketmezsiniz, fakat Fiddler yada Postman gibi Web Api araçları kullanarak bunu inceleme şansınız mevcuttur.

 

Header içinde bulunan alanlardan bazıları aşağıdadır;

  • HOST - Girilen URL ana domain örneğin google.com gibi
  • Accept, Content-Type - Sayfanın text,html,xml,json olup olmadığı ve dil kodunu (Utf8 vb.) içerir.
  • Accept, Content-Encoding - Sayfanın transfer edilirken sıkıştırılıp , sıkıştırılmadığı
  • User Agent - Kullanılan browsera ait bilgileri içerir.

Response Body ise Content type kısmında belirtilen formatta tarayıcıya iletilen bilgidir. Web Api de bu bilgi POST edilirken JSON veya GET isteği sonucu XML veya JSON olarak karşımızda çıkacaktır. Web sayfalarında ise genellikle text/html'dir. Tarayıcıdayken sayfaya sağ tıklayıp incele dediğimizde dönen text/html kodunu görebiliriz.

 

REST ve RESTful Kavramı

Representational State Transer- Temsili Durum Transferine uygun olarak geliştirilen servislere RESTful servisler denir. WCF SOAP aksine sabit URL adresleri yerine değişken URL adresleri kullanılır.

  • SOAP - GetSiparisler (http://sunucum/api sabit URL üzerinden talep edilir).
  • REST- http://sunucum/api/GetSiparisler, http://sunucum/api/GetSiparisler/1, http://sunucum/api/GetSiparisler/2/sipdurumu(Yapılmak istenene göre URL dinamikleştirilir. Sipariş durumu 2 yani bekleyen siparisler için request URL kullanılmıştır).

REST mimarisi 2000li yıllarda Roy Thomas Fielding tarafından doktora tezi olarak savunulmuştur. Tez linki: https://www.ics.uci.edu/~fielding/pubs/dissertation/fielding_dissertation.pdf

RESTful servisler REST mimarisini kullanan platform bağımsız ve az yükle çalışan hizmetlerdir (Android, Linux, Windows, IoT cihazları sunucunuzdaki bu servise bağlanabilir).

  • Genellikle XML veya JSON formatında response üretirler. İstenirse Custom formattada sonuç üretebilirler.
  • Client-Server hakkında bilgi sahibi değildir. Sadece URL bilgisine sahiptir.
  • Server'da Client hakkında bilgi sahibi değildir. Bu yüzden Session kullanımı yoktur (Stateless denilen Temsili Durum Transferi - REST buradan gelmektedir.).
  • Sunucu Cacheable bilgisi sunuyorsa client tarafından cachelenebilir.
  • Client hangi katmana bağlandığını bilmez (Layered System).
  • Client ve Server arasında URI formatlı ortak bir arayüz bulunur.
  • Opsiyonel olarak Client tarafında program çalıştırılmasına yönelik Client Side Script gönderimi sağlanabilir (Code on Demand).

Test Araçları

Başkası yada kendimiz tarafından yapılan Web Apilerin çalıştırılarak sınanması amacıyla aşağıdaki araçları kullanabilirsiniz. Hata oranını azaltmanın yanında Header bilgilerinin görüntülenmesi, hazır URL kısaltma ve önceden yapılan taleplerin liste şeklinde kaydedilerek topluca test edilmesi vb. bir çok özellik içermektedirler. Aşağıda bulunan linklerden detay öğrenebilirsiniz.

ASP.NET Web Api İlk Uygulama

İlk uygulamamızı yapmadan önce kısaca Routing kavramından bahsetmek istiyorum.

Convention Base Routing (Kurallara Dayalı Yönlendirme)

Yazılan api metod isimleri içerisinde Get, Post, Put, Delete var ise MVC otomatik olarak yapılan talebe göre ilgili metodu icra edecektir.

İki tane Get metodu var ise bunlardan metod imzası uygun olan çağrılacaktır. İmzaları aynı olan iki metod varsa api 500 kodlu sunucu hatası döndürecektir.

// GET api/values http://sunucum/api/values URL'si ile okunabilir.
public IEnumerable<string> Get()
{
        return values;
}

// GET api/values http://sunucum/api/values/7 URL'si ile okunabilir. Yani fazladan gönderilen 7 nolu değer bize 7 nolu kaydı döndürecektir.
public IEnumerable<string> Get(int id) 
{ 
        return values[id];
}

 

Action Base Routing (Eyleme Dayalı Yönlendirme)

Metod öncesinde ilgili metodun hangi eylemi destekleyeceğine dair Attribute belirtilir. Bu durumda metod ismi içinde Get,Post,Put,Delete kullanılmasına gerek olmamaktadır.

[HttpGet]
public IEnumerable<string> VeriCek()

{
        return values;
}
[HttpPost] 
public void VeriEkle([FromBody] string value)
{
        values.Add(value);
}

Attribute Base Routing (Özniteliğe Bağlı Yönlendirme)

Api metodunun üst kısmına istenen nitelikte özel bir routing yazılmasıyla sağlanır.

[Route("api/Siparisler/{id}/sipdurumu")]
public IEnumerable<string> OrdersByStatus(int id)
{
 //gerekli kodlar
 return List<string>;
}

Api Controllerımız içinde Get,Post,Put,Delete ve bunların farklı imzalı metodları olabilir. Bu durumda her seferinde uzun uzun route atribute yazmak yerine ApiController sınıfı başında RoutePrefix kullanabiliriz.

[RoutePrefix("api/Siparisler")]

Bu durumda bir önceki örnekteki route ifademiz [Route("{id}/sipdurumu")] olacaktır. Tüm kayıtlar dönecek olan Get metodumuz için [Route("")] yazmak yeterli olacaktır. Herhangi bir metodta RoutePrefix'imizi ezmek istersek tilda (~) kullanmamız gerekiyor. Örn: [Route("~/api/ozelsiparisler")]

Örneğin iki tane Get metodumuz var ve biri Id diğeri ise isim bekliyor. Bu durumda metod imzasında kısıtlayıcı kullanmadığınız durumda 500 sunucu hatası ile karşılaşacaksınız. Aşağıda basit bir Constraint örneği bulunmaktadır. Kısıtlayıcı karışıklığın önüne geçerek isteğin doğru metoda yönlendirilerek icra edilmesini sağlayacaktır. Ayrıca id değeri minimum , maksimum vb. bir çok aralıkta kısıtlanabilir. Daha fazla detay için microsoft dokümanlarına göz atmanızı öneririm.

[Route("{id:int}")]
public Musteriler Get(int id) {//gerekli kodlar; return musteri;}

[Route("{isim:alpha}")]
public Musteriler Get(string isim) {//gerekli kodlar; return musteri;}

Kendimize ait özel kısıtlayıcı yazmak istersek IHttpRouteConstraint sınıfından kalıtım alarak true yada false dönen bir constraint class oluşturmalıyız. Daha sonra oluşturduğumuz bu sınıfı WebApiConfig içinde new DefaultInlineConstraintResolver() olarak instance etmeli ardından config.MapHttpAttributeRoutes(örnekinstanceadi) şeklinde belirtmeliyiz.

Route içinde Default ve Opsiyonel Kullanımı

Bu konu gayet basit ve anlaşılır olduğundan kısaca tarifleyeceğim. Route Constraint içinde ? işareti ile betimleme yaparsak bu paramatre artık opsiyonel oluyor ve boş gönderilebilir. Bu durumda metodumuzun çalışması için boş olduğu durumda id değerimize değer atarsak bu da default değer oluyor.

[Route ("detay/{id:decimal?}")]
public Musteriler Get (decimal id = 1) //Boş geçilirse 1 nolu müşteri kaydı dönecektir.
{
        return Customers.FirstOrDefault(m=> m.Id == id);
}

Route Name ve Link Özelliği

POST işlemi sonucunda veritabanına eklenen bir datayı Header'da paylaşarak verinin gerçekten eklenip eklenmediğinin kontrolü istenebilir. Bunun için RouteName ile Get metodumuza isim vererek, Post metodunda Route.Link ile yeni kayda ait api linkini elde edebiliriz.

Önce Get metodumuza Name özelliği ile isim ekleyelim.

[Route("{id:int}, Name = GetById")]
public Musteriler Get (int id)
{
     return Customers.FirstOrDefault(m=> m.Id == id);
}

Sonra Post metodumuzda ekleme işlemi tamamlanınca yeni yaratılan kayda ait URL'yi Header'a ekleyelim.

[Route("ekle")]
public HttpResponceMessage Post(Customer cust)
{
        cust.Id = Customers.Max(x=> x.Id) + 1 ;
        Customers.Add(cust);
       
        HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created);
        response.Headers.Location = new Uri(Url.Link("GetById", new { id = cust.Id}));
        return response;

}

Routing konusunda daha detaylı bilgi için buradan microsoft dokümanlarına göz atabilirsiniz.

Yukarıda anlatılanları bir uygulama videosuyla yakında ekleyeceğim... Makale devam edecek...