修改 wordpress 模版,windows优化大师官方,企业网站最重要的访问对象是,长宁区网站制API升级#xff0c;新旧版本的API共存#xff0c;怎么管理呢#xff1f;一、前言最近#xff0c;单位APP做了升级#xff0c;同步的#xff0c;API也做了升级。升级过程中#xff0c;出现了一点问题#xff1a;API升级后#xff0c;旧API也需要保留#xff0c;因为有… API升级新旧版本的API共存怎么管理呢 一、前言最近单位APP做了升级同步的API也做了升级。升级过程中出现了一点问题API升级后旧API也需要保留因为有旧的APP还在使用中。那么API端如何作到多个版本共存呢二、快速的解决办法API的露出是在API的Route定义中实现的。看下面的例子[Route(api/[controller])]
public class DemoController : ControllerBase
{[Route(demo)]public ActionResultT DemoFunc(){}
}
那我们知道这个API的终结点是/api/demo/demo。代码中[controller]是个可替换变量编译时会替换为当前控制器的名称。这个Route里面的参数是个字符串也就是说是可以随便换的。所以对于多版本API有个快速的办法就是在里面做文章。我们可以写成[Route(api/v1/[controller])]
public class DemoController : ControllerBase
{[Route(demo)]public ActionResultT DemoFunc(){}
}
或者[Route(api/[controller])]
public class DemoController : ControllerBase
{[Route(v1/demo)]public ActionResultT DemoFunc(){}
}
这样就区分出了版本号。 当然这样做比较LOW因为版本号是硬编码在代码中的。而且这个改动会影响到API的终结点例如上面两个变化会让终结点变为/api/v1/demo/demo和/api/demo/v1/demo。如果前端可以方便修改也算是一个方法。但对于我们APP已经上线运行来说这个改动无法接受。三、优雅的解决办法这个方案才是今天要说的核心内容。 首先我们需要从Nuget上引入两个库% dotnet add package Microsoft.AspNetCore.Mvc.Versioning
% dotnet add package Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer
这两个库Versioning用来实现API的版本控制Versioning.ApiExplorer用来实现元数据的发现工作。引入完成后修改Startup.cspublic void ConfigureServices(IServiceCollection services)
{services.AddApiVersioning(options {options.DefaultApiVersion new ApiVersion(1, 0);options.AssumeDefaultVersionWhenUnspecified true;options.ReportApiVersions true;});services.AddVersionedApiExplorer(options {options.GroupNameFormat vVVV;options.SubstituteApiVersionInUrl true;});services.AddControllers();
}
就可以了。这里面用了两个配置AddApiVersioning主要用来配置向前兼容定义了如果没有带版本号的访问会默认访问v1.0的接口。AddVersionedApiExplorer用来添加API的版本管理并定义了版本号的格式化方式以及兼容终结点上带版本号的方式。到这儿引入版本管理的工作就完成了。 使用时就直接在控制器或方法上定义版本号[ApiVersion(1)]
[Route(api/[controller])]
public class DemoController : ControllerBase
{[MapToApiVersion(2)][Route(demo)]public ActionResultT DemoFunc(){}
}
这里面又是两个属性ApiVersion定义控制器提供哪个版本的API。这个属性可以定义多个。例如我们控制器里既有v1的API也有v2的API我们可以写成[ApiVersion(1)]
[ApiVersion(2)]
[Route(api/[controller])]
public class DemoController : ControllerBase
{
}
MapToApiVersion是API的版本定义定义我们这个API是哪一个版本。方法就这么简单。其它的微软都帮我们做好了。 那通常我们会用Swagger来做API文档。这个方法如何跟Swagger配合呢四、与Swagger的配合Swagger也来自于Nuget的引用% dotnet add package swashbuckle.aspnetcore
引用后通常我们Startup.cs里的配置是这样的public void ConfigureServices(IServiceCollection services)
{services.AddSwaggerGen(option {option.SwaggerDoc(v1, new OpenApiInfo { Title Demo, Version V1 });});services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{app.UseSwagger();app.UseSwaggerUI(option {option.SwaggerEndpoint(/swagger/v1/swagger.json, Demo);});}API多版本管理与Swagger配合也有一个快速但比较LOW的方法public void ConfigureServices(IServiceCollection services)
{services.AddSwaggerGen(option {option.SwaggerDoc(v1, new OpenApiInfo { Title Demo, Version V1 });option.SwaggerDoc(v1, new OpenApiInfo { Title Demo, Version V2 });});services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{app.UseSwagger();app.UseSwaggerUI(option {option.SwaggerEndpoint(/swagger/v1/swagger.json, Demo V1);option.SwaggerEndpoint(/swagger/v2/swagger.json, Demo V2);});
}
这个方法也可以快速实现不过跟上边的情况一样版本号是硬编码的。 其实也有另一个比较优雅的方式就是手动实现IConfigureOptionsSwaggerGenOptions和过滤IOperationFilter。先看Startup.cs里public void ConfigureServices(IServiceCollection services)
{services.AddTransientIConfigureOptionsSwaggerGenOptions, ConfigureSwaggerOptions();services.AddSwaggerGen(options options.OperationFilterSwaggerDefaultValues());services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{app.UseSwagger();app.UseSwaggerUI(option {foreach (var description in provider.ApiVersionDescriptions){c.SwaggerEndpoint($/swagger/{description.GroupName}/swagger.json, description.GroupName.ToUpperInvariant());}});
}
这里加了两个类第一个ConfigureSwaggerOptionsinternal class ConfigureSwaggerOptions : IConfigureOptionsSwaggerGenOptions
{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 CreateInfoForApiVersion(ApiVersionDescription description){var info new OpenApiInfo(){Title Demo API,Version description.ApiVersion.ToString(),};if (description.IsDeprecated){info.Description 方法被弃用.;}return info;}
}
第二个SwaggerDefaultValuesinternal class SwaggerDefaultValues : IOperationFilter
{public void Apply(OpenApiOperation operation, OperationFilterContext context){var apiDescription context.ApiDescription;operation.Deprecated | apiDescription.IsDeprecated();if (operation.Parameters null)return;foreach (var parameter in operation.Parameters){var description apiDescription.ParameterDescriptions.First(p p.Name parameter.Name);if (parameter.Description null){parameter.Description description.ModelMetadata?.Description;}if (parameter.Schema.Default null description.DefaultValue ! null){parameter.Schema.Default new OpenApiString(description.DefaultValue.ToString());}parameter.Required | description.IsRequired;}}
}
代码不一行行解释了都是比较简单的。 运行进入Swagger界面右上角Select a definition可以选择我们定义的版本号。 今天的配套代码已上传到Github位置在https://github.com/humornif/Demo-Code/tree/master/0035/demo喜欢就来个三连让更多人因你而受益