ASP.NET Core API Versioning

Merhabalar,

Geliştirdiğimiz mobil uygulamalarımızda web api konusu en az uygulama kadar önemlidir. Çünkü mobil uygulamalarımızın dış dünya ile haberleşmesini API katmanları ile sağlarız. Bu blog yazımda sizlere ASP.NET Core ile geliştirdiğimiz API projelerimizde versiyonlamayı nasıl yapacağımızı anlatacağım.

Detaylı bir şekilde ASP.NET Core ile API geliştirme video anlatımı yolda 🙂

API versioning, API katmanımızın güvenliği ve kod kalitesi gibi kavramları kadar önemli bir nokta. Çünkü geliştirdiğimiz uygulamaların isterlerini versiyonlayarak yönetmek bize birçok noktada rahat bir development alanı sağlayacaktır ve eğer dökümantasyon yapıyorsak hizmet verdiğimiz son kullanıcılar için de güzel bir kılavuz olacaktır. Konumuz “API Projelerimizi Versiyonlamanın Önemi” olmadığı için kısa geçiyorum fakat konunun ayrı bir blog-post serisi olması gerektiğini de eklemek isterim 🙂

API Versioning’i;

projelerinizde kullanabilirsiniz.

Örneğimi ASP.NET Core API üzerinden yapacağım için nuget yardımıyla ASP.NET Core API paketini projeme yükleyeceğim.

Şimdi projemize yeni bir TestController ekleyelim.

    [Route("[controller]")]
    [ApiController]
    public class TestController : ControllerBase
    {
        [HttpGet]
        public string Get()
        {
            return "api versioning";
        }
    }

26 Ekim 2019 tarihinde ASP.NET Core 3.0 uygulamanız için 4.0.0-preview8.19405.7 sürümünü kullanmanız gerekiyor.

https://github.com/microsoft/aspnet-api-versioning/issues/499

Startup classımızın ConfigureServices methodunda ufak bir değişiklikle başlayalım..

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc(options => options.EnableEndpointRouting = true).SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Latest);
            services.AddApiVersioning();
            services.AddControllers();
        }

AddApiVersioning methodu ile en basit şekilde versiyonlamaya başlayabiliyoruz. Fakat bundan sonraki ilk requestinizde muhtemelen aşağıdaki hatayı alacaksınız.

{
 "error": {
 "code": "ApiVersionUnspecified",
 "message": "An API version is required, but was not specified.",
 "innerError": null
 }
}

Artık isteklerimizi yaparken hangi versiyon altındaki hizmetleri kullanacağımızı söylememiz gerekiyor.

  • test?api-version=1.0
  • test?api-version=xxx
  • test/v1/
  • test/vxxx/
  • test/v{date}

Çok daha fazla türetilebilir. buradaki 1 major 0 ise minor versiyonu temsil etmekte.

Daha önce yazdığınız API’ların versiyon durumundan etkinlenmesini istemiyorsanız, AddApiVersioning methodunu ApiVersioningOptions classındaki bazı özellikleri doldurarak kullanmanız gerekmektedir. AssumeDefaultVersionWhenUnspecified ve DefaultApiVersion özellikleri size yardımcı olacaktır. Buradaki DefaultApiVersion özelliğine major ve minor versiyon vererek veya bir tarih belirterek bu işlemi yapabilirsiniz.

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc(options => options.EnableEndpointRouting = true).SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Latest);
            //services.AddApiVersioning();
            services.AddApiVersioning((option) =>
            {
                option.AssumeDefaultVersionWhenUnspecified = true;
                option.DefaultApiVersion = new ApiVersion(new DateTime(2017, 1, 1));
            });
            services.AddControllers();
        }

Senaryomuz yeni bir API geliştirmek üzerine olduğu için benim böyle bir ihtiyacım yok. Fakat option içerisinde direkt kullanmak istediğim ReportApiVersions özelliği mevcut. Bu özellik; Tüm geçerli API url’leri için HTTP header’da “api-supported-versions” ve “api-deprecated-versions” durumlarını dönüyor.

TestController üzerine attribute ekleyerek API supported versiyon durumunu güncelleyebiliriz. Eğer [ApiVersion(“2.0”)] gibi bir kullanımımız olursa, “api-supported-versions” değeri 2.0 olacaktır.

İstediğimiz bir method’a parametre olarak ApiVersion classını verebiliriz. Bu sayede method dönüşlerinde kullanılan API ile ilgili bilgileri dönebiliriz.

        public string Get(ApiVersion version)
        {
            return $"{version.MajorVersion}.{version.MinorVersion}";
        }

TestController v1 olarak dursun ben v2 olarak Test2Controller açtım ve TestController’a ?api-version=2.0 olarak istekte bulunduğumda, Test’ does not support the API version ‘2.0’ hatasını alacağım. Test2?api-version=2.0 olarak istekte bulunursam cevap Status 200 olarak dönecektir. Aslında tek bir attribute kullanarak API Versioning paketi benim için arkada bu durumları handle ediyor.

Route attribute üzerinde değişiklik yaparak isteklerimizi şekillendirebiliriz. [Route(“v{version:apiVersion}/[controller]”)] gibi bir değişiklik v2.0/values gibi bir istek bekleyecektir.

Peki ya aynı controller içerisinde 2 tane Get methodumuz olsa ve bu methodlar v2 ve v3 olarak çalışsa… vsvs yani bu kadar kırılım yapabiliyor muyuz? EVET!

namespace APIVersioning.Controllers
{
    [ApiVersion("2.0")]
    [Route("[controller]")]
    [ApiController]
    public class Test2Controller : ControllerBase
    {
        [HttpGet]
        public string Get(ApiVersion version)
        {
            return $"{version.MajorVersion}.{version.MinorVersion}";
        }
        [HttpGet]
        public string Getv3(ApiVersion version)
        {
            return $"{version.MajorVersion}.{version.MinorVersion}";
        }
    }
}

Startup classımızda da Controller bazında methodları kırarak, x method y versiyonunu kullanıyor demeliyiz.

            services.AddApiVersioning((options) =>
            {
                options.ReportApiVersions = true;
                options.Conventions.Controller<TestController>().HasApiVersion(1, 0);
                options.Conventions.Controller<Test2Controller>()
                                       .HasApiVersion(2, 0)
                                       .HasApiVersion(3, 0)
                                       .Action(c => c.Getv3(default)).MapToApiVersion(3, 0);
            });

Kaynaklar : https://github.com/Microsoft/aspnet-api-versioning

Yiğit ÖZAKSÜT

MVP, MCT, Xamarin Developer, Consultant & Architect

1 Yorum

You can post comments in this post.


  • Çok güzel bir anlatım olmuş hocam devamını bekliyoruz 🙂

    Erdoğan 3 hafta ago Reply


Yorum Gönder