.NET Api Versioning

API versiyonlama, uygulamaların sürekli gelişimi ve değişen ihtiyaçlara uygun hale getirilmesi gerektiğinde, mevcut API’lerin bozulmadan yeni özellikler veya iyileştirmelerin sunulmasına olanak tanır. .NET Core (veya .NET 6/7/8 gibi modern sürümler) API’lerde versiyonlama işlemini kolaylaştıran çeşitli yöntemler sunar. Bu yazıda, API versiyonlamanın neden gerekli olduğunu, .NET Core’da nasıl uygulanacağını ve bu süreçte dikkate alınması gereken bazı önemli noktaları detaylandıracağız.

API Versiyonlama Neden Önemlidir?

API’ler, istemcilerin (client) bir sunucu ile etkileşim kurmasını sağlayan arayüzlerdir. Zamanla bu API’ler üzerinde değişiklikler yapılması gerekebilir: yeni özellikler eklenebilir, performans iyileştirmeleri yapılabilir ya da eski yöntemler kaldırılabilir. Ancak mevcut API’yi kullanan istemcilerin, bu değişiklikler yüzünden sorun yaşamaması gerekir. İşte bu noktada API versiyonlama devreye girer. Versiyonlama, bir API’nin eski sürümlerinin korunmasını ve aynı anda yeni sürümlerin kullanılabilmesini sağlar.

.NET Core’da API Versiyonlama Yöntemleri

.NET Core’da API versiyonlama işlemi için en yaygın kullanılan kütüphane Microsoft.AspNetCore.Mvc.Versioning paketidir. Bu paket, farklı versiyonlama stratejileriyle birlikte esneklik sağlar. Şimdi bu stratejilere ve nasıl uygulanacaklarına bakalım.

1. URL Tabanlı Versiyonlama

Bu yöntem, API versiyonunu URL içerisinde belirtmeye dayanır. Örneğin:

/api/v1/products
/api/v2/products

Bu yöntem, versiyonun görünürlüğü açısından oldukça popülerdir çünkü istemci tarafında kolayca anlaşılır. Ancak, her yeni versiyon için farklı bir URL kullanılması gerektiği için URL yapısı zamanla karmaşık hale gelebilir.

Nasıl Uygulanır?

  1. Projeye Microsoft.AspNetCore.Mvc.Versioning paketini eklememiz gerekiyor
dotnet add package Microsoft.AspNetCore.Mvc.Versioning

2. Startup.cs dosyasında API versiyonlamayı yapılandırması:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddApiVersioning(options =>
    {
        options.AssumeDefaultVersionWhenUnspecified = true;
        options.DefaultApiVersion = new ApiVersion(1, 0);
        options.ReportApiVersions = true;
        options.ApiVersionReader = new UrlSegmentApiVersionReader();
    });
}

3. Contoller tarafına ekleyelim

[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("1.0")]
public class ProductsController : ControllerBase
{
    [HttpGet]
    public IActionResult Get() => Ok("Products v1");
}

[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("2.0")]
public class ProductsV2Controller : ControllerBase
{
    [HttpGet]
    public IActionResult Get() => Ok("Products v2");
}

Bu örnek, aynı Products kaynağı için iki farklı versiyon tanımlıyor.

2. Query String Tabanlı Versiyonlama

Versiyon numarasını URL parametresi olarak geçmek de oldukça yaygın bir yöntemdir. Örneğin:

/api/products?api-version=1.0
/api/products?api-version=2.0

Bu yöntem, URL’yi temiz tutsa da, bazen istemci tarafında versiyon belirtmenin unutulması veya yanlış yapılması gibi sorunlara yol açabilir.

Nasıl Uygulanır? ApiVersionReader yerine QueryStringApiVersionReader kullanarak yapılandırma yapılabilir:

services.AddApiVersioning(options =>
{
    options.AssumeDefaultVersionWhenUnspecified = true;
    options.DefaultApiVersion = new ApiVersion(1, 0);
    options.ReportApiVersions = true;
    options.ApiVersionReader = new QueryStringApiVersionReader("api-version");
});

3. Header Tabanlı Versiyonlama

Bu yöntem, istemcilerin versiyonu HTTP başlıklarında belirtmesine dayanır. Örneğin, istemci şu başlıkla istekte bulunur:

GET /api/products HTTP/1.1
Api-Version: 1.0

Bu yöntem URL’yi temiz tutar ve daha temiz bir API kullanımı sağlar. Ancak, başlıkların doğru şekilde yönetilmesi gerektiğinden istemci tarafında ek yapılandırmalar gerekebilir.

Nasıl Uygulanır? HeaderApiVersionReader kullanarak yapılandırabilirsiniz:

services.AddApiVersioning(options =>
{
    options.AssumeDefaultVersionWhenUnspecified = true;
    options.DefaultApiVersion = new ApiVersion(1, 0);
    options.ReportApiVersions = true;
    options.ApiVersionReader = new HeaderApiVersionReader("Api-Version");
});

4. Medya Tabanlı Versiyonlama (Media Type Versioning)

Bu yöntem, versiyonun içerik tipine (Content-Type) dahil edilmesine dayanır. İstemci, versiyonu şu şekilde belirtir:

GET /api/products HTTP/1.1
Accept: application/json;v=1.0

Bu yöntem, versiyonlamayı oldukça esnek hale getirir ve genellikle RESTful API’ler için önerilen bir yaklaşımdır.

Nasıl Uygulanır?

services.AddApiVersioning(options =>
{
    options.AssumeDefaultVersionWhenUnspecified = true;
    options.DefaultApiVersion = new ApiVersion(1, 0);
    options.ReportApiVersions = true;
    options.ApiVersionReader = new MediaTypeApiVersionReader();
});

Versiyonlama Stratejisi Seçimi

Hangi versiyonlama yönteminin kullanılacağı, API’nin kullanım senaryolarına ve kullanıcı kitlesine bağlıdır. URL tabanlı versiyonlama, versiyonların daha görünür olmasını sağlarken; header ve medya tabanlı versiyonlama URL’yi temiz tutar, ancak istemci tarafında daha fazla yapılandırma gerektirir. Projenize en uygun stratejiyi belirlerken, mevcut API’lerinizi kullanan istemcilerin yapılandırmalarını ve API kullanım alışkanlıklarını göz önünde bulundurmalısınız.

Çoklu Versiyonları Desteklemek

Bazen bir API’nin farklı versiyonlarını aynı anda desteklemek gerekebilir. .NET Core, birden fazla API versiyonunu paralel olarak yönetmeye olanak tanır. Bir controller üzerinde birden fazla versiyon belirtilebilir:

[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("1.0")]
[ApiVersion("2.0")]
public class ProductsController : ControllerBase
{
    [HttpGet, MapToApiVersion("1.0")]
    public IActionResult GetV1() => Ok("Products v1");

    [HttpGet, MapToApiVersion("2.0")]
    public IActionResult GetV2() => Ok("Products v2");
}

Bu şekilde, hem eski sürümü kullanan istemciler hem de yeni sürümü kullananlar için aynı ProductsController üzerinden farklı yanıtlar dönebilirsiniz.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir