swagger的多个版本

Multiple versions of swagger

本人是swagger新手,按照文档搭建模板,非常成功。但是我现在有2个版本的API,每个版本都是从上一个版本迭代过来的,我想保留每个版本的API,请问怎么办?非常感谢任何帮助。

[ApiVersion("1")]  
[ApiVersion("2")]  
[ApiController]  
[Route("api/v{version:apiVersion}/[controller]")]  
public class DummyController : ControllerBase  
{
    [HttpGet]    
    [MapToApiVersion("1")]    
    [Route("Test")]    
    public your_return_type TestV1() { ... }
      
      
    [HttpGet]    
    [MapToApiVersion("2")]    
    [Route("Test")]    
    public your_return_type TestV2() { ... }
}

api/v1/dummy/test
api/v2/dummy/test

我之前写过一个demo,你可以参考一下,也许就是你想要的。

使用的版本:

ASP.NET Core 3.1
Swashbuckle.AspNetCore: 5.4.1

首先我创建了2个版本的文件夹和controllers.Therefore,每个控制器的命名空间对应它的文件夹,像这样:

V1版本

namespace WebApplication129.Controllers.V1
{
    [ApiController]
    [Route("api/v1/[controller]")]
    public class HomeController : ControllerBase
    {

       [Route("test")]
        [HttpGet]
        public string Test()
        {
            return "v1 test";
        }
    }
}

V2版本

namespace WebApplication129.Controllers.V2
{
    [ApiController]
    [Route("api/v2/[controller]")]
    public class HomeController : ControllerBase
    {

        [Route("test")]
        [HttpGet]
        public string Test()
        {
            return "v2 test";
        }
    }
}

然后创建一个协议通知Swagger,这样我们就可以控制Swagger如何生成Swagger文档,从而控制UI.

创建以下 class:

public class GroupingByNamespaceConvention : IControllerModelConvention
{
    public void Apply(ControllerModel controller)
    {
        var controllerNamespace = controller.ControllerType.Namespace;
        var apiVersion = controllerNamespace.Split(".").Last().ToLower();
        if (!apiVersion.StartsWith("v")) { apiVersion = "v1"; }
        controller.ApiExplorer.GroupName = apiVersion;
    }
}

我们所做的是根据命名空间的最后一段对控制器进行分组。因此,命名空间以 v1 结尾的控制器将被分组为名称“v1”,以 v2 结尾的控制器将被分组为“v2”,等等

现在我们必须应用约定。为此,我们转到 ConfigureServices 中的 AddControllers 并添加约定:

services.AddControllers(options =>
{
    options.Conventions.Add(new GroupingByNamespaceConvention());
});

最终完成的startup.cs配置如下:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using System;
using WebApplication129.Controllers.conf;

namespace WebApplication129
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers(options =>
            {
                options.Conventions.Add(new GroupingByNamespaceConvention());
            });

            services.AddSwaggerGen(config =>
            {
                var titleBase = "Test API";
                var description = "This is a Web API for Test operations";
                var TermsOfService = new Uri("https://xxxxxx");
                var License = new OpenApiLicense()
                {
                    Name = "Test"
                };
                var Contact = new OpenApiContact()
                {
                    Name = "Test",
                    Email = "Test@hotmail.com",
                    Url = new Uri("https://xxxxxx")
                };

                config.SwaggerDoc("v1", new OpenApiInfo
                {
                    Version = "v1",
                    Title = titleBase + " v1",
                    Description = description,
                    TermsOfService = TermsOfService,
                    License = License,
                    Contact = Contact
                });

                config.SwaggerDoc("v2", new OpenApiInfo
                {
                    Version = "v2",
                    Title = titleBase + " v2",
                    Description = description,
                    TermsOfService = TermsOfService,
                    License = License,
                    Contact = Contact
                });
            });
        }

       
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseSwagger();
            app.UseSwaggerUI(config =>
            {
                config.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
                config.SwaggerEndpoint("/swagger/v2/swagger.json", "v2");
            });
            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

访问url:https://localhost:yourport/swagger/index.html