Web Api Projelerinde Versiyonlama

Yazmış olduğunuz Api projelerinde versiyonlama yapmak oldukça önemlidir. Düzenli bir versiyonlama yaparak hem mevcut hemde yeni versiyonu kullanacak olan client'lar için tutarlı response'lar sağlayabilirsiniz. Örneğin v1.0 için çalışan listesi dönen bir api metodu yazdınız ve mevcutta kullanan kullanıcılar var. production'da. Sonra v2.0 de dediler ki çalışan isimlerinin yanında departman kodu da yazsın (Caner Tosuner, IT gibi). Her ne kadar kullanıcılar v2.0 geliştirmesini yapacak olsalarda belli bir süre daha eski versiyon için destek veriyor olmak gerekir çünkü bütün herkes aynı anda v2.0'a geçemeyebilir veya v1.0 da kalmak isteyebilir. İşte bu gibi durumları en iyi şekilde yönetilmemiz için versiyonlamayı son derece iyi yapmamız gerekir.

Web Api için versiyonlama yapmanın ortak kabul görmüş bir kaç yol bulunmakta;

  • URL de versiyon bilgisini query string olarak geçebiliriz,
  • Request Header'a "appVersion" gibi bir key/value ekleyebiliriz,
  • Genelde media type için kullanılsada AcceptHeader'a versiyon bilgisini ekleyebiliriz,
  • Her request'te BaseRequest'te içerisinde bir versiyon bilgisini alma.

Yukarıda sıralanan 4 yol da versiyonlama için çözüm ancak WebApi'ın son sürümüyle birlikte tercih edilmemeye başlandı hatta ve hatta yanlış çözüm olarak söyleyenler bile mevcut.

WebApi için versiyonlamayı Api metodlarının başına attribute olarak ekleyeceğimiz Route class'ı bulunmakta. Bu class'ı kullanarak kısaca hangi url bilgisi ile o metod çağrılabilir onu belirtmiş oluyoruz.

Burda dikkat etmemiz gereken konuların başında elimizden geldiğince mevcut URL'i bozmamaız gerekiyor.

Şimdi gelelim örneğimize.

Yukarıda bahsettiğimiz örnek üzerinden ilerleyelim ve EmployeeController adında bir ApiController'ımız var ve içerisinde GetEmployeeList() adında bir metod olsun. Bu metod öncelikle v1.0 için geriye çalışan adı ve soyadı bilgilerini içeren bir string array dönsün.

        [HttpGet]
        [Route("api/v1/Employee/{GetEmployeeList}")]
        public IHttpActionResult GetEmployeeList()
        {
            var list = new string[] { "İlhan Mansız", "Tümer Metin" };

            return Ok(list);
        }

Yukarıda ki gibi v1.0 için kullanıcılar bu metodu kullanmakta. GetEmployeeList() metoduna request'te bulunmak için url "http://localhost/api/v1/Employee/GetEmployeeList".

Ancak v2.0 da ad soyad bilgisinin yanında bir de departman adı istenmekte İlhan Mansız, Pazarlama gibi.

Şimdide v2.0 metodunu yazalım.

        [HttpGet]
        [Route("api/v2/Employee/{GetEmployeeList}")]
        public IHttpActionResult GetEmployeeListV2()
        {
            var list = new string[] { "İlhan Mansız, Pazarlama", "Tümer Metin, Satış" };

            return Ok(list);
        }

v2.0 metodunuda yazdık. Bu metoda request'te bulunmak için url "http://localhost/api/v2/Employee/GetEmployeeList".

Yukarıda da bahsettiğmiz gibi en dikkat etmemiz gerekn konuların başında client'ın yapacağı request'i ve api url'ini elimizden geldiğinde aynı tutmak ve bütün versiyonlarda url için değişen tek şeyin versiyon numarası olduğunu belirtmek. Böylelikle service tarafı için ayrımı url de bulunan versiyon numarasından alarak yapabiliriz.

Route attribute'ü kullanmadan versiyonlama işlemini farklı controller'lar kullanarak ta yapabilirsiniz. Üstteki örneğimizde olduğu gibi GetEmployeeList() meetodlarını içeren 2 farklı EmployeeV1Controller ve EmployeeV2Controller adında controller'lar tanımlayabiliriz. Url route işini de WebApiConfig.cs class'ı içerisine yine yukarıdaki url'leri kullanarak gerekli controller'lar da bulunan metodlara yönlendirmeleri yapabilirsiniz. Örneğin şu şekilde;

config.Routes.MapHttpRoute(
            name: "ApiV1_Route",
            routeTemplate: "api/v1/{controller}/{id}",
            defaults: new { controller = "EmployeeV1Controller", action = "GetEmployeeList", id = RouteParameter.Optional }
            );

config.Routes.MapHttpRoute(
            name: "Apiv2_Route",
            routeTemplate: "api/v2/{controller}/{id}",
            defaults: new { controller = "EmployeeV2Controller", action = "GetEmployeeList", id = RouteParameter.Optional }
            );

Yine "http://localhost/api/v1/Employee/GetEmployeeList" metoduna istekte bulunduğumuzda yukarıda yaptığımız config'den dolayı EmployeeV1Controller'ında bulunan GetEmployeeList metoduna yönlendirecektir. v2 için ise EmployeeV2Controller'ında bulunan GetEmployeeList metoduna yönlendirecektir.

 

Versiyonlama büyük çapta olan projeler için oldukça önemlidir. Production'a uygulamanızı çıktıktan sonraki zaman içerisinde tekrardan update'ler çıkmaya devam edeceksinizdir ve versiyonlama yaparak bu işlemleri yürütüyor olmak hem kolaylıklar sağlar hem de projenizi daha yönetilebilir hale getirir.

Add comment