Executando verificação de segurança...
1

📚 Como Adicionar Suporte a MĂșltiplas VersĂ”es de API com Swagger no ASP.NET Core 🔄

Gerenciar mĂșltiplas versĂ”es de uma API pode parecer um desafio, mas Ă© algo essencial quando vocĂȘ precisa manter compatibilidade com clientes antigos enquanto continua evoluindo seu sistema. Neste artigo, vamos explorar como configurar o suporte a mĂșltiplas versĂ”es de API no ASP.NET Core com Swagger (via Swashbuckle). Vamos direto ao ponto!

1. Configurando o Versionamento da API

Primeiro, adicione o pacote necessĂĄrio:

Install-Package Microsoft.AspNetCore.Mvc.Versioning

Depois, configure o versionamento no Program.cs:

builder.Services.AddApiVersioning(options =>
{
    options.DefaultApiVersion = new ApiVersion(1);
    options.ReportApiVersions = true;
    options.AssumeDefaultVersionWhenUnspecified = true;
    options.ApiVersionReader = ApiVersionReader.Combine(
        new UrlSegmentApiVersionReader(),
        new HeaderApiVersionReader("X-Api-Version"));
}).AddApiExplorer(options =>
{
    options.GroupNameFormat = "'v'V";
    options.SubstituteApiVersionInUrl = true;
});
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>();

O que acontece aqui?

  • DefaultApiVersion: Define a versĂŁo padrĂŁo da API (1.0).
  • ReportApiVersions: Adiciona informaçÔes sobre as versĂ”es no cabeçalho HTTP.
  • AssumeDefaultVersionWhenUnspecified: Usa a versĂŁo padrĂŁo se nenhuma for informada.
  • ApiVersionReader: Permite ler a versĂŁo da API via URL ou cabeçalho HTTP.
  • GroupNameFormat: Agrupa as versĂ”es no Swagger com o formato v1, v2, etc.
  • SubstituteApiVersionInUrl: Substitui corretamente o placeholder {version} na URL.

No fim das contas, vocĂȘ terĂĄ uma API que sabe lidar com mĂșltiplas versĂ”es de forma elegante.


2. Criando Controladores com Suporte a VersÔes

Vamos adicionar um controlador com suporte a duas versÔes:

[ApiVersion(1)]
[ApiVersion(2)]
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
public class WeatherForecastController : ControllerBase
{
    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

    private readonly ILogger<WeatherForecastController> _logger;

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

    [MapToApiVersion(1)]
    [HttpGet(Name = "GetWeatherForecast")]
    public IEnumerable<WeatherForecast> Get()
    {
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
            TemperatureC = Random.Shared.Next(-20, 55),
            Summary = Summaries[Random.Shared.Next(Summaries.Length)]
        }).ToArray();
    }

    [MapToApiVersion(2)]
    [HttpGet(Name = "GetWeatherForecast")]
    public IEnumerable<WeatherForecast> GetV2()
    {
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
            TemperatureC = Random.Shared.Next(0, 55),
            Summary = Summaries[Random.Shared.Next(Summaries.Length)]
        }).ToArray();
    }
}

O que acontece aqui?

  • ApiVersion: Define que o controlador suporta mĂșltiplas versĂ”es.
  • MapToApiVersion: Direciona mĂ©todos especĂ­ficos para versĂ”es especĂ­ficas.
  • Rota: A versĂŁo Ă© passada na URL com {version:apiVersion}.

Importante: Em uma arquitetura de versionamento real, é comum que endpoints da mesma rota em versÔes diferentes possam ter:

  • ParĂąmetros diferentes: Uma versĂŁo pode exigir um parĂąmetro adicional ou usar um tipo diferente.
  • Respostas diferentes: O formato ou os campos do DTO podem variar entre versĂ”es.
  • Comportamento diferente: A lĂłgica por trĂĄs do mesmo endpoint pode ser alterada.

No exemplo acima, ambas as versÔes retornam o mesmo tipo de resposta, mas é importante lembrar que, em cenårios reais, isso pode mudar.


3. Configurando o Swagger para VersÔes de API

Agora, precisamos garantir que o Swagger exiba corretamente as versÔes. Para isso, criamos uma classe personalizada:

public class ConfigureSwaggerOptions : IConfigureOptions<SwaggerGenOptions>
{
    private readonly IApiVersionDescriptionProvider _provider;

    public ConfigureSwaggerOptions(IApiVersionDescriptionProvider provider)
    {
        _provider = provider;
    }

    public void Configure(SwaggerGenOptions options)
    {
        foreach (var description in _provider.ApiVersionDescriptions)
        {
            options.SwaggerDoc(description.GroupName, CreateInfoForApiVersion(description));
        }
    }

    private OpenApiInfo CaAgorapiVersionDescription description)
    {
        return new OpenApiInfo
        {
            Title = "Weather API",
            Version = description.ApiVersion.ToString(),
            Description = description.IsDeprecated ? "Esta versĂŁo foi descontinuada." : "VersĂŁo ativa da API"
        };
    }
}

Aqui, cada versão da API recebe sua própria documentação Swagger.


4. Configurando o Middleware Swagger

Por fim, adicionamos os endpoints Swagger no middleware:

app.UseSwaggerUI(options =>
{
    var descriptions = app.DescribeApiVersions();
    foreach (var description in descriptions)
    {
        options.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
    }
});

5. Testando no Swagger

Rode sua aplicação e acesse https://localhost:<porta>/swagger. LĂĄ, vocĂȘ verĂĄ cada versĂŁo listada separadamente. Clique e teste!


ConclusĂŁo

Agora vocĂȘ tem mĂșltiplas versĂ”es de API rodando no ASP.NET Core com suporte completo no Swagger. Esse setup garante que vocĂȘ possa manter compatibilidade com clientes antigos enquanto continua evoluindo suas APIs.

Para mais detalhes, confira o repositĂłrio oficial: WebApiVersioningDemo.

Carregando publicação patrocinada...