API Versiyonlama - NET 6 Web API

API geliştirip yayınladıktan sonra iyileştirme veya ek özellik eklenmesi için çalışma yapılabilir. Bu çalışmalar köklü bir hale geliyorsa API versiyonlama konusu ile sürüm oluşturma çözümüne gidebiliriz. 

Başlıca API versiyon oluşturulabilecek nedenler;

  • Müşterinin talepleri, mevcut yapıda değişiklik yapmayı gerektiriyorsa,
  • Teknoloji (veri tabanı veya ek kütüphane kullanımı) veya mimari (monolitikten mikroservise geçiş) değişiklikler uygulandıysa,
  • Bilgilendirme ve değişikliklerin takibi (Hangi versiyonda ne gibi özelliklerin geldiği)
  • Media Type değişiklikleri (json, formdata, xml vb.)
Versiyonlamanın çıkış nedenini anladığımıza göre ortak kabul gören versiyonlama tekniklerine giriş yapalım.

HTTP Header

Versiyon bilgisini doğrudan urlde göstermek yerine header bilgisi ile gönderiyoruz. En sık görülen header örneği aşağıdaki gibidir.
X-API-Version: 1.0
Ayrıca istemci tarafında API'nin hangi versiyonunu istersek versiyon numarasını header bilgisine atayıp gönderebiliriz.

Url

En sık görebileceğiniz versiyonlama tipidir. Bu tipte API'nin versiyon bilgisi url'de bulunur. REST mimarisinin url prensibine ters düşebilir. Ayrıca yeni bir versiyon geldiğinde API'yı kullanan müşteriler, uygulamalarında güncelleme yapmak zorunda kalacaktır. 

xyz.com/v1.0/categories
xyz.com/v1.1/category/1

Query String

Bu versiyonlama tipinde versiyon bilgisi, query string parametresi ile istek olarak gönderilir. Diğer query string parametreleriyle karıştırılabilir. Uygulama yapılandırma ayarlarında, hangi parametre olduğunu ayarlayarak kullanılabilir.

xyz.com/v1.0/categories?api-version=1.0

Versiyonlama tekniklerini .NET 6 Web API projesinde uygulanmasını görelim. 

Create New Project ile bir Web API projesi oluşturduktan sonra NET 6 seçtiğimize emin olmalıyız.


Web API projesi oluşturulduktan sonra Nuget Package Manager'den aşağıdaki paketi yüklememiz gerekir. 
Nuget Linki: Microsoft.AspNetCore.Mvc.Versioning

Bu projenin dokümantasyonu, incelediğim kadarıyla güzel bir kaynaktır. İncelemek için buraya tıklayabilirsiniz. 


Yüklemeyi tamamladıktan sonra Program.cs dosyasından API versiyonlamayı kullanabileceğimiz servis metodunu ekleyelim.
builder.Services.AddApiVersioning();

AddApiVersioning metodunda sık kullanılan ayarları options parametresi ile yapabiliriz.


DefaultApiVersion: Eğer istekte belirli bir versiyon bilgisi gönderilmediğinde verilen varsayılan versiyon bilgisidir. Microsoft.AspNetCore.Mvc.ApiVersion sınıfında major ve minor bilgisi sırasıyla verilir. 
new Microsoft.AspNetCore.Mvc.ApiVersion(1, 0);
Örneğin; v1.0 için  şeklinde major:1 minor: 0 olarak atanmıştır.

AssumeDefaultVersionWhenUnspecified: API versiyonu gönderilmediğinde varsayılan olarak v1.0 da çalışmasını sağlayan bir özelliktir. Varsayılan olarak false olup, true olarak ayarlanırsa varsayılan versiyon v1.0 olarak çalışacaktır. True verilmediğinde aşağıdaki gibi bir uyarı dönecektir.

ReportApiVersions: Tarayıcıda response headers alanında desteklenen/desteklenmeyen api versiyon bilgilerini göstermek için eklenir. 

Desteklenmeyen API versiyonu için: api-deprecated-versions: 1.0 
Desteklenen API versiyonu için: api-supported-versions: 2.0

Deprecated versiyon ayarlamasını Controller metodunda ApiVersion attributesindeki Deprecated parametresi true ayarlanarak yapılabilir. 
[ApiVersion("1.0",Deprecated =true)]

ApiVersionReader: API versiyonunun okunması için belirttiğimiz kaynaktır. Herhangi bir tanım yapmazsak, varsayılan olarak versiyon bilgisini query string'den alacağı  QueryStringApiVersionReader sınıfıdır. 

Verebileceğimiz diğer bir değer, versiyon bilgisinin HTTP header'den alacağı 
HeaderApiVersionReader sınıfıdır. Kullanılma şekilleri aşağıdaki gibidir.
  • options.ApiVersionReader = new QueryStringApiVersionReader("api-version");
  • options.ApiVersionReader = new HeaderApiVersionReader("X-API-Version");

Parametre olarak aldıkları değerler, parametrenin isimleridir. İstediğimiz isimlendirmeyi yapabiliriz.  

Projede controller tarafında versiyona göre klasörlere ayrıldı. Düzenli olması adına tavsiye ediyorum. Gelin controller sınıflarının detaylarını inceleyelim.


ProductController version 1 için ApiVersion değeri "1.0" tanımlandı. 

ProductController version 2 için ApiVersion değeri "2.0" tanımlandı. 

Controllerda herhangi bir metodu farklı bir versiyona da bağlayabiliriz. V2 için oluşturduğum ProductsController sınıfında ApiVersion değeri "3.0" olarak tanımlandı. Versiyon 3 te çalışacak GetAllProductsV3 metodunun üzerinde MapToApiVersion değeri 3.0 olarak ayarlandı. Bunun anlamı versiyon bilgisi 3.0 gönderildiğinde GetAllProductsV3 metot çalışacaktır. Aynı sınıftan versiyon bağlama örneğini görmüş olduk.


Örnekte üç versiyon arasındaki en önemli senaryo farkı, v1.0 da GetAllProducts metodu bütün ürünleri getirirken, v2.0 da bu metot sadece 3 tane ürün getirecektir. v3.0 da ise 10 adet ürün getirecektir. Bu istekleri makalenin başında belirttiğim 3 versiyon teknikleriyle uygulanmasını görelim. 

Http Header

Bu teknik için Postman üzerinden çıktıyı görelim. Projede ApiVersionReader değerini HeaderApiVersionReader ile tanımlayalım ve ismine "X-API-Version" verelim. Postman'de header verirken bu ismi kullanacağız.



Query String

Projede ApiVersionReader değerine bir atama yapmadığımızda varsayılan olarak çalışan teknik olduğundan bahsetmiştim. Endpoint sonrasına verilen query stringde versiyon bilgisi, 2.0 olarak aşağıdaki şekilde verildi. 

Url

Url yapısında ise Controller tarafındaki Route attributesine aşağıdaki gibi düzenleme yapmamız gerekir.
[Route("api/v{version:apiVersion}/[controller]")]

Gönderdiğimiz versiyona göre eşleşen controller sınıfına istek gönderir. Örnekte versiyon 2 için url şemasına aşağıdaki gibi gönderim yapıldı.

https://localhost:44396/api/v2/products 


Bu makalenin sonuna gelirken; Api versiyonlama sebeplerini anlayıp, url, header ve query string yöntemleriyle versiyonlamayı inceledikten sonra .NET 6 Web API projesinde uygulanmasını görmüş olduk.

Örnek projeye Github repo linkinden ulaşabilirsiniz.

Keyifli ve faydalı olmasını umarak, çalışmalarınızda kolaylıklar diliyorum...

Yorumlar