17 Ocak 2025

ASP.NET Web API Versiyonalama

Orjinal ve Detaylı Makale

https://weblogs.asp.net/ricardoperes/asp-net-core-api-versioning

------

1) Aşağıda ki paketleri kurun

  • Asp.Versioning.Mvc
  • Asp.Versioning.Mvc.ApiExplorer
  • Swashbuckle.AspNetCore

2) Versiyonları elle yazmamak için ben SVApiVersion adında bir class oluşturdum. (Opsiyonel)

  public static class SVApiVersion
  {
      public static class V1
      {
          public const int Major = 1;
          public const int Minor = 0;
          public const string Version = "1.0";
      }

      public static class V2
      {
          public const int Major = 2;
          public const int Minor = 0;
          public const string Version = "2.0";
      }
  }

3) ConfigureSwaggerOptions swagger için gerekli classı oluşturun.

 internal class ConfigureSwaggerOptions : IConfigureOptions<SwaggerGenOptions>
 {
     private readonly IApiVersionDescriptionProvider _provider;
     private readonly IOptions<ApiVersioningOptions> _options;

     public ConfigureSwaggerOptions(IApiVersionDescriptionProvider provider, IOptions<ApiVersioningOptions> options)
     {
         _provider = provider;
         _options = options;
     }

     public void Configure(SwaggerGenOptions options)
     {
         foreach (var description in _provider.ApiVersionDescriptions)
         {
             var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
             var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);

             if (File.Exists(xmlPath))
             {
                 options.IncludeXmlComments(xmlPath);
             }

             options.SwaggerDoc(description.GroupName, CreateVersionInfo(description));
         }
     }

     private OpenApiInfo CreateVersionInfo(ApiVersionDescription description)
     {
         var info = new OpenApiInfo()
         {
             Title = $"API {description.GroupName}",
             Version = description.ApiVersion.ToString()
         };

         if (description.ApiVersion == _options.Value.DefaultApiVersion)
         {
             if (!string.IsNullOrWhiteSpace(info.Description))
             {
                 info.Description += " ";
             }

             info.Description += "Default API version.";
         }

         if (description.IsDeprecated)
         {
             if (!string.IsNullOrWhiteSpace(info.Description))
             {
                 info.Description += " ";
             }

             info.Description += "This API version is deprecated.";
         }

         return info;
     }
 }


4) Program.cs ye aşağıda ki gibi gerekli servisleri tanımladım.(Sonradan eklenenler bold)


using Asp.Versioning;
using Asp.Versioning.ApiExplorer;
using SampleVersioningAPI;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddApiVersioning(options =>
{
    options.AssumeDefaultVersionWhenUnspecified = true;
    options.DefaultApiVersion = new ApiVersion(SVApiVersion.V1.Major, SVApiVersion.V1.Minor);
    options.ReportApiVersions = true;
    options.ApiVersionReader = ApiVersionReader.Combine(
        new UrlSegmentApiVersionReader(),
        new HeaderApiVersionReader("X-Version"));
}).AddApiExplorer(options =>
{
    options.GroupNameFormat = "'v'VVV";
    options.SubstituteApiVersionInUrl = true;
});


builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.ConfigureOptions<ConfigureSwaggerOptions>();


var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI(c =>
    {
        var provider = app.Services.GetRequiredService<IApiVersionDescriptionProvider>();
        foreach (var description in provider.ApiVersionDescriptions)
        {
            c.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());

        }
    });

}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();


5) Ben API Controller Yapısını Aşağıda ki Gibi Yaptım (Opsiyonel)

Farklı kullanım şekilleri orjinal makalede vardır.


- Controllers / V1 / ValuesController
- Controllers / V2 / ValuesController

Controller aşağıdaki gibidir.


namespace SampleVersioningAPI.Controllers.V1
{
    [ApiController]
    [ApiVersion(SVApiVersion.V1.Version)]
    [Route("api/v{version:apiVersion}/[controller]")]

    public class ValuesController : ControllerBase
    {

        private readonly ILogger<ValuesController> _logger;

        public ValuesController(ILogger<ValuesController> logger)
        {
            _logger = logger;
        }

        [HttpGet()]
        public string Get()
        {
            return SVApiVersion.V1.Version;
        }
    }
}

using Asp.Versioning;
using Microsoft.AspNetCore.Mvc;

namespace SampleVersioningAPI.Controllers.V2
{
    [ApiController]
    [ApiVersion(SVApiVersion.V2.Version)]
    [Route("api/v{version:apiVersion}/[controller]")]

    public class ValuesController : ControllerBase
    {
        private readonly ILogger<ValuesController> _logger;

        public ValuesController(ILogger<ValuesController> logger)
        {
            _logger = logger;
        }

        [HttpGet()]
        public string Get()
        {
            return SVApiVersion.V2.Version;
        }
    }
}


Github Kaynak Kodu: https://github.com/AmagiTech/AspNetApiVersionSample