如何动态实现api版本控制和swagger文档

She*_*han 3 api .net-core

我正在 dotnet core api 工作。我必须在 api 上实现版本控制。swagger文档应该按api版本分类。

Dal*_*ary 5

在 .NetCore api 版本控制中,可以通过添加来自 nuget 的以下引用来实现

  1. Microsoft.AspNetCore.Mvc.版本控制
  2. Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer

添加引用后,请在项目的启动文件中执行以下操作。在 AddMvc 行之前添加以下行。我将使用 Header-api 版本控制。这意味着客户端将在标头中提及版本。标题名称是可定制的。

 services.AddApiVersioning(this.Configuration);
Run Code Online (Sandbox Code Playgroud)

AddApiVersioning 的定义如下(在不同的扩展类中):

public static void AddApiVersioning(this IServiceCollection services, IConfiguration configuration)
{
    services.AddApiVersioning(apiVersioningOptions =>
    {
        apiVersioningOptions.ApiVersionReader = new HeaderApiVersionReader(new string[] { "api-version" }); // It means version will be define in header.and header name would be "api-version".
        apiVersioningOptions.AssumeDefaultVersionWhenUnspecified = true;
        var apiVersion = new Version(Convert.ToString(configuration["DefaultApiVersion"]));
        apiVersioningOptions.DefaultApiVersion = new ApiVersion(apiVersion.Major, apiVersion.Minor);
        apiVersioningOptions.ReportApiVersions = true;
        apiVersioningOptions.UseApiBehavior = true; // It means include only api controller not mvc controller.
        apiVersioningOptions.Conventions.Controller<AppController>().HasApiVersion(apiVersioningOptions.DefaultApiVersion);
        apiVersioningOptions.Conventions.Controller<UserController>().HasApiVersion(apiVersioningOptions.DefaultApiVersion);               
        apiVersioningOptions.ApiVersionSelector = new CurrentImplementationApiVersionSelector(apiVersioningOptions);
    });
    services.AddVersionedApiExplorer(); // It will be used to explorer api versioning and add custom text box in swagger to take version number.
}
Run Code Online (Sandbox Code Playgroud)

这里configuration[“DefaultApiVersion”]是appsetting中的一个键,值为1.0如上面的代码所示,我们使用Convention来定义每个控制器的api版本。当只有一个 api 版本并且您不想使用 [ApiVersion] 属性标记每个控制器时,它非常有用。

如果您不想使用约定方法来定义控制器的版本。使用属性标签来定义版本。就像下面这样:

[Route("[controller]")]
[ApiController]
[ApiVersion("1.0")]
public class TenantController : ConfigController
Run Code Online (Sandbox Code Playgroud)

完成此操作后,转到启动文件并添加以下代码。

 app.UseApiVersioning(); //Here app is IApplicationBuilder
Run Code Online (Sandbox Code Playgroud)

这是 api 版本控制的完整解决方案。

对于 swagger 我们必须添加 nuget 包,定义如下:

  1. 虚张声势.AspNetCore
  2. Swashbuckle.AspNetCore.SwaggerGen
  3. Swashbuckle.AspNetCore.SwaggerUI 添加引用后,执行以下操作:在 Services.UseApiVersioning() 之后添加以下行

services.AddSwaggerGenerationUI();

AddSwaggerGenerationUI 的定义如下:

public static void AddSwaggerGenerationUI(this IServiceCollection services)
{
    var provider = services.BuildServiceProvider()
                     .GetRequiredService<IApiVersionDescriptionProvider>();
    services.AddSwaggerGen(action =>
    {                
        action.OrderActionsBy(orderBy => orderBy.HttpMethod);
        action.UseReferencedDefinitionsForEnums();
        foreach (var item in provider.ApiVersionDescriptions)
        {
            action.SwaggerDoc(item.GroupName, new Swashbuckle.AspNetCore.Swagger.Info
            {
                Title = "Version-" + item.GroupName,
                Version = item.ApiVersion.MajorVersion.ToString() + "." + item.ApiVersion.MinorVersion
            });
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

此代码将在管道中添加 swagger。现在我们必须使用 swagger。在启动文件中执行以下代码:

app.UseSwaggerGenerationUI(this.Configuration)
Run Code Online (Sandbox Code Playgroud)

UseSwaggerGenerationUI 的定义如下:

public static void UseSwaggerGenerationUI(this IApplicationBuilder applicationBuilder, IApiVersionDescriptionProvider apiVersionDescriptionProvider, IConfiguration configuration)
{
    applicationBuilder.UseSwagger(c =>
    {
        c.RouteTemplate = "/api/help/versions/{documentname}/document.json";

        c.PreSerializeFilters.Add((swaggerDoc, httpReq) => swaggerDoc.BasePath = "/api");
    });

    applicationBuilder.UseSwaggerUI(c =>
    {
        c.RoutePrefix = "api/help";
        c.DocumentTitle = "Api Help";
        foreach (var item in apiVersionDescriptionProvider.ApiVersionDescriptions)
        {
            c.SwaggerEndpoint($"/api/help/versions/{item.GroupName}/document.json", item.GroupName);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)