Search code examples
c#asp.net-coreswaggerwebapi.net-8.0

How to setup a beta versioning in Swagger endpoint?


In my WebApi project (c# and .net8) I successfully setup the following definition:

ApiExplorerSettings(GroupName)

For version 1.0 I have these endpoints:

Swagger definition

However for beta I wanna have something like: /beta/api/Auth/Logon. Almost similar to what Microsoft have with their Graph Explorer endpoint:

Graph Endpoint

Currenty I'm using version 2.0 to distinguish api versions. Any idea how to do this? This what I have in the code:

namespace My.API.Controllers
{
   [ApiVersion("2.0")]
   [Route("v{version:apiVersion}/api/[controller]")]
   [ApiController]
   public class AdminController : ControllerBaseExtra
   {
       private readonly ILoggerManager _logger;
       private readonly IConfiguration _configuration;
       private readonly ISessionUtility _sessionUtility;
       private HttpClient _client;

       public AdminController(ISessionUtility sessionUtility, IConfiguration configuration, ILoggerManager logger)
       {
           _configuration = configuration;
           _logger = logger;
           _sessionUtility = sessionUtility;
           _client = new HttpClient(new LoggingHandler(logger, new HttpClientHandler()));
       }

       /// <summary>
       /// Gets list of available environments.
       /// </summary>
       /// <returns></returns>
       [AllowAnonymous]
       [HttpGet]
       [Route("/v{version:apiVersion}/api/[controller]/Environments")]
       [ApiExplorerSettings(GroupName = "beta")]
       [ProducesResponseType(type: typeof(List<GWEnvironments>), statusCode: 200)]
       [ProducesResponseType(type: typeof(string), statusCode: 400)]
       [Produces("application/json", "application/xml")]
       public ActionResult<List<GWEnvironments>> Environments()
       {
       }
  }

}

Thank's in advance.


Solution

  • ApiVersion has a prescribed format which cannot be changed. This is important for collation, sorting, and comparison. For example, 1.0, 1.0-beta. You could define like:[ApiVersion(1.0,"beta")].

    Actually no need define the ApiVersion for your beta api which can also achieve your requirement, just add the [Route] and [ApiExplorerSettings] attribute like below:

    [Route("beta/api/[controller]")]
    [ApiController]
    [ApiExplorerSettings(GroupName = "beta")]
    public class BetaAdminController : ControllerBase
    {
        [HttpGet]
        [Route("Logon")]
        public IActionResult BetaLogon()
        {
            // Beta API method
            return Ok("Beta Logon successful");
        }
    }
    

    Be sure the Program.cs configure like below:

    using Microsoft.AspNetCore.Builder;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    using Microsoft.OpenApi.Models;
    using Asp.Versioning;
    
    var builder = WebApplication.CreateBuilder(args);
    
    // Add services to the container.
    
    builder.Services.AddControllers();
    // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen(options =>
    {
        // Generate Swagger documentation for both versions
        options.SwaggerDoc("v1", new OpenApiInfo { Title = "My API v1", Version = "v1" });
        options.SwaggerDoc("beta", new OpenApiInfo { Title = "My Beta API", Version = "beta" });
    });
    builder.Services.AddApiVersioning(options =>
    {
        options.ReportApiVersions = true;
        options.AssumeDefaultVersionWhenUnspecified = true;
        options.DefaultApiVersion = new ApiVersion(1, 0);
        options.ApiVersionReader = new UrlSegmentApiVersionReader();
    }).AddApiExplorer(options =>
    {
        options.GroupNameFormat = "'v'VVV";
        options.SubstituteApiVersionInUrl = true;
    });
    
    builder.Services.AddProblemDetails();
    var app = builder.Build();
    
    // Configure the HTTP request pipeline.
    if (app.Environment.IsDevelopment())
    {
        app.UseSwagger();
        //app.UseSwaggerUI();
        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
            c.SwaggerEndpoint("/swagger/beta/swagger.json", "Beta");
        });
    }
    
    app.UseHttpsRedirection();
    app.UseExceptionHandler();
    
    app.UseAuthorization();
    
    app.MapControllers();
    
    app.Run();
    

    Also be sure add the package:

    <PackageReference Include="Asp.Versioning.Http" Version="8.1.0" />
    <PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.1.0" />