4.使用媒体类型(Media Type)参数,如 Accept: application/json;v=2.0
[Version Group.]<Major>.<Minor>[-Status] <Version Group>[<Major>[.Minor]][-Status]版本组的格式为YYYY-MM-DD,它能够对API接口起到逻辑分组的作用,状态则能够标识当前版本的状况,如Alpha、Beta和RC等。以下是常见的版本格式:
/api/foo?api-version=1.0 /api/foo?api-version=2.0-Alpha /api/foo?api-version=2015-05-01.3.0 /api/v1/foo /api/v2.0-Alpha/foo /api/v2015-05-01.3.0/foo本文采用 /api/v1/foo 形式
Asp.Versioning.Mvc Asp.Versioning.Mvc.ApiExplorer四.注册服务
builder.Services.AddApiVersioning(options => { // 堆代码 duidaima.com options.DefaultApiVersion = new ApiVersion(1, 0); options.AssumeDefaultVersionWhenUnspecified = true; options.ReportApiVersions = true; options.ApiVersionReader = ApiVersionReader.Combine( new UrlSegmentApiVersionReader(), new HeaderApiVersionReader("x-api-version"), new MediaTypeApiVersionReader("ver") ); }) .AddMvc() .AddApiExplorer(options => { options.GroupNameFormat = "'v'VVV"; options.SubstituteApiVersionInUrl = true; });以上代码做了这些事:
Format Specifier | Description | Examples |
---|---|---|
F | Full API version as [group version][.major[.minor]][-status] | 2017-05-01.1-RC -> 2017-05-01.1-RC |
FF | Full API version with optional minor version as [group version][.major[.minor,0]][-status] | 2017-05-01.1-RC -> 2017-05-01.1.0-RC |
G | Group version as yyyy-MM-dd | 2017-05-01.1-RC -> 2017-05-01 |
GG | Group version as yyyy-MM-dd with status | 2017-05-01.1-RC -> 2017-05-01-RC |
y | Group version year from 0 to 99 | 2001-05-01.1-RC -> 1 |
yy | Group version year from 00 to 99 | 2001-05-01.1-RC -> 01 |
yyy | Group version year with a minimum of three digits | 2017-05-01.1-RC -> 017 |
yyyy | Group version year as a four-digit number | 2017-05-01.1-RC -> 2017 |
M | Group version month from 1 through 12 | 2001-05-01.1-RC -> 5 |
MM | Group version month from 01 through 12 | 2001-05-01.1-RC -> 05 |
MMM | Group version abbreviated name of the month | 2001-06-01.1-RC -> Jun |
MMMM | Group version full name of the month | 2001-06-01.1-RC -> June |
d | Group version day of the month, from 1 through 31 | 2001-05-01.1-RC -> 1 |
dd | Group version day of the month, from 01 through 31 | 2001-05-01.1-RC -> 01 |
ddd | Group version abbreviated name of the day of the week | 2001-05-01.1-RC -> Mon |
dddd | Group version full name of the day of the week | 2001-05-01.1-RC -> Monday |
v | Minor version | 2001-05-01.1-RC -> 1 1.1 -> 1 |
V | Major version | 1.0-RC -> 1 2.0 -> 2 |
VV | Major and minor version | 1-RC -> 1 1.1-RC -> 1.1 1.1 -> 1.1 |
VVV | Major, optional minor version, and status | 1-RC -> 1-RC 1.1 -> 1.1 |
VVVV | Major, minor version, and status | 1-RC -> 1.0-RC 1.1 -> 1.1 1 -> 1.0 |
S | Status | 1.0-Beta -> Beta |
p | Padded minor version with default of two digits | 1.1 -> 01 1 -> 00 |
p[n] | Padded minor version with N digits | p2: 1.1 -> 01 p3: 1.1 -> 001 |
P | Padded major version with default of two digits | 2.1 -> 02 2 -> 02 |
P[n] | Padded major version with N digits | P2: 2.1 -> 02 P3: 2.1 -> 002 |
PP | Padded major and minor version with a default of two digits | 2.1 -> 02.01 2 -> 02.00 |
PPP | Padded major, optional minor version, and status with a default of two digits | 1-RC -> 01-RC 1.1-RC -> 01.01-RC |
PPPP | Padded major, minor version, and status with a default of two digits | 1-RC -> 01.00-RC 1.1-RC -> 01.01-RC |
/api/v1/demo/test /api/v2/demo/test在 Controller 下创建俩目录,v1 和 v2,然后分别创建Controller
[Route("api/v{version:apiVersion}/[controller]")] [ApiVersion(1.0)] [ApiController] public class DemoController : ControllerBase { [HttpGet("[action]")] public ApiResponse Test() { return ApiResponse.Ok("version=1.0"); } }另一个版本的接口 Controllers/v2/DemoController.cs
[Route("api/v{version:apiVersion}/[controller]")] [ApiVersion(2.0)] [ApiController] public class DemoController : ControllerBase { [HttpGet("[action]")] public ApiResponse Test() { return ApiResponse.Ok("version=2.0"); } }可以看到要区分不同版本的接口,只需要添加 [ApiVersion(2.0)] 特性即可。因为我要使用URL来选择不同版本的接口,所以要把路由配置为 "api/v{version:apiVersion}/[controller]"
public class ConfigureSwaggerOptions : IConfigureOptions<SwaggerGenOptions> { readonly IApiVersionDescriptionProvider provider; public ConfigureSwaggerOptions(IApiVersionDescriptionProvider provider) => this.provider = provider; public void Configure(SwaggerGenOptions options) { foreach (var description in provider.ApiVersionDescriptions) { options.SwaggerDoc( description.GroupName, new OpenApiInfo() { Title = $"Example API {description.ApiVersion}", Version = description.ApiVersion.ToString(), }); } } }注册服务
// 堆代码 duidaima.com builder.Services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>();配置中间件
app.UseSwagger(); app.UseSwaggerUI(options => { foreach (var description in app.DescribeApiVersions()) { var url = $"/swagger/{description.GroupName}/swagger.json"; var name = description.GroupName.ToUpperInvariant(); options.SwaggerEndpoint(url, name); } });八.效果 & 测试
{ "statusCode": 200, "successful": true, "message": "version=1.0", "data": null, "errorData": null }请求 https://localhost:7053/api/v2/Demo/Test
{ "statusCode": 200, "successful": true, "message": "version=2.0", "data": null, "errorData": null }不错