1. 優點
- 有助於保護原有系統,不受影響,並及時修改問題
- 可以實現用戶的私人定制(比如是付費接口)
- 快速迭代
2. API版本控制
- 在URL中追加版本或者作為查詢字符串參數
- 通過自動以標頭和通過接受標頭
2.1 安裝組件
ASP.NET API versioning為您提供了一種功能強大但易於使用的方法,用於將API版本控制語義添加到使用ASP.NET構建的新的和現有的REST服務中。API版本控制擴展定義了簡單的元數據屬性和約定,用於描述您的服務實現了哪些API版本。
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="4.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer" Version="4.2.0" />
2.1.1 常用配置
[ApiVersion("1.1")] //設置版本號
[ApiVersionNeutral]//退出版本控制
[MapToApiVersion("1.1")] //設置獨立版本
[ApiVersion("1.0", Deprecated = true)]//api版本已經被棄用
HttpContext.GetRequestedApiVersion().ToString(); //訪問版本信息
2.2 QueryString來實現版本控制
2.2.1 ConfigureServices中配置
//Versioning用來實現API的版本控制
services.AddApiVersioning(options =>
{
options.DefaultApiVersion = new ApiVersion(1, 1);//默認版本號
options.AssumeDefaultVersionWhenUnspecified = true;//此選項將用於不提供版本的請求,默認情況下假定API的版本為1.0
options.ReportApiVersions = true;//當設置為true時候,api將返回響應標頭中支持的版本信息
//下面這句默認不寫也可以
//options.ApiVersionReader = new QueryStringApiVersionReader(parameterNames: "api-version");//該名稱用於查詢時候使用
});
2.2.2 控制器設置版本
namespace NetCore_SwaggerVersion.Controllers.v1
{
/// <summary>
/// 版本1.1
/// </summary>
[Route("api/[controller]")]
[ApiController]
[ApiVersion("1.1")]//可以設置多個
[ApiVersion("1.2")]
public class TestController : ControllerBase
namespace NetCore_SwaggerVersion.Controllers.v2
{
/// <summary>
/// 版本2.0
/// </summary>
[Route("api/[controller]")]
[ApiController]
[ApiVersion("2.6")]
public class TestController : ControllerBase
不同命名空間下可以存在相同的控制器
2.2.3 特定方法設置版本
[MapToApiVersion("1.1")]
[HttpGet]
public IEnumerable<string> Get()
2.2.4 設置不受版本控制
[ApiVersionNeutral]//退出版本控制
[ApiController]
[Route("api/[controller]/[action]")]
public class WeatherForecastController : ControllerBase
2.3.5 訪問地址
http://localhost:5000/api/WeatherForecast/Get //不寫版本號的話走的是默認的版本號
http://localhost:5000/api/Test?api-version=1.1
http://localhost:5000/api/Test?api-version=1.2
http://localhost:5000/api/Test?api-version=2.6
2.3 URL Path Segment來實現版本控制
2.3.1 ConfigureServices中配置
//Versioning用來實現API的版本控制
services.AddApiVersioning(options =>
{
options.DefaultApiVersion = new ApiVersion(1, 1);//默認版本號
options.AssumeDefaultVersionWhenUnspecified = true;//此選項將用於不提供版本的請求,默認情況下假定API的版本為1.0
options.ReportApiVersions = true;//當設置為true時候,api將返回響應標頭中支持的版本信息
});
2.3.2 控制器設置版本
namespace NetCore_SwaggerVersion.Controllers.v1
{
/// <summary>
/// 版本1.1
/// </summary>
[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]
[ApiVersion("1.0")]
[ApiVersion("1.1")]//定義控制器提供哪個版本的API
public class TestController : ControllerBase
namespace NetCore_SwaggerVersion.Controllers.v2
{
/// <summary>
/// 版本2.0
/// </summary>
[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]
[ApiVersion("2.6")]
public class TestController : ControllerBase
不同命名空間下可以存在相同的控制器
2.3.3 特定方法設置版本
[MapToApiVersion("1.1")]
[HttpGet]
public IEnumerable<string> Get()
2.3.4 設置不受版本控制
[ApiVersionNeutral]//退出版本控制
[ApiController]
[Route("api/[controller]/[action]")]
public class WeatherForecastController : ControllerBase
2.3.5 訪問地址
http://localhost:5000/api/v1.0/Test
http://localhost:5000/api/v1.1/Test
http://localhost:5000/api/v2.6/Test
http://localhost:5000/api/WeatherForecast/Get 不受版本控制
2.4 HTTP Headers來實現版本控制
2.4.1 ConfigureServices中配置
//Versioning用來實現API的版本控制
services.AddApiVersioning(options =>
{
options.DefaultApiVersion = new ApiVersion(1, 1);//默認版本號
options.AssumeDefaultVersionWhenUnspecified = true;//此選項將用於不提供版本的請求,默認情況下假定API的版本為1.0
options.ReportApiVersions = true;//當設置為true時候,api將返回響應標頭中支持的版本信息
//header傳遞版本信息
options.ApiVersionReader = new HeaderApiVersionReader("version");
options.ApiVersionSelector = new CurrentImplementationApiVersionSelector(options);//如果沒有傳輸版本號,那么會使用最大版本號 LowestImplementedApiVersionSelector是最小版本號
options.UseApiBehavior = false;//是否使用API行為
});
2.4.2 控制器設置版本
namespace NetCore_SwaggerVersion.Controllers.v1
{
/// <summary>
/// 版本1.1
/// </summary>
[Route("api/[controller]")]
[ApiController]
[ApiVersion("1.1")]//定義控制器提供哪個版本的API
public class TestController : ControllerBase
namespace NetCore_SwaggerVersion.Controllers.v2
{
/// <summary>
/// 版本2.0
/// </summary>
[Route("api/[controller]")]
[ApiController]
[ApiVersion("2.6")]
public class TestController : ControllerBase
不同命名空間下可以存在相同的控制器
2.4.3 特定方法設置版本
[MapToApiVersion("1.1")]
[HttpGet]
public IEnumerable<string> Get()
2.4.4 設置不受版本控制
[ApiVersionNeutral]//退出版本控制
[ApiController]
[Route("api/[controller]/[action]")]
public class WeatherForecastController : ControllerBase
2.4.5 訪問地址
http://localhost:5000/api/Test //需要在headers里面增加 version: 1.1
http://localhost:5000/api/WeatherForecast/Get 不受版本控制
2.5 同時支持多種模式
services.AddApiVersioning(o =>
{
o.ReportApiVersions = true;
o.AssumeDefaultVersionWhenUnspecified = true;
o.DefaultApiVersion = new ApiVersion(1, 0);
o.ApiVersionReader = ApiVersionReader.Combine(new HeaderApiVersionReader("api-version"), new QueryStringApiVersionReader("api-version"));
//或者
//同時支持查詢字符串和標頭
o.ApiVersionReader = new QueryStringOrHeaderApiVersionReader(parameterName: "version"){HeaderNames = { "api-version", "x-ms-version" }}
});
2.6 不借助包,封裝文件
public class NameSpaceVersionRoutingConvention:IApplicationModelConvention
{
private readonly string apiPrefix;
private const string urlTemplate = "{0}/{1}/{2}";
public NameSpaceVersionRoutingConvention(string apiPrefix = "api")
{
this.apiPrefix = apiPrefix;
}
public void Apply(ApplicationModel application)
{
foreach (var controller in application.Controllers)
{
var hasRouteAttribute = controller.Selectors
.Any(x => x.AttributeRouteModel != null);
if (!hasRouteAttribute)
{
continue;
}
var nameSpaces = controller.ControllerType.Namespace.Split('.');
//獲取namespace中版本號部分
var version = nameSpaces.FirstOrDefault(x => Regex.IsMatch(x, @"^v(\d+)$"));
if (string.IsNullOrEmpty(version))
{
continue;
}
string template = string.Format(urlTemplate, apiPrefix, version,
controller.ControllerName);
controller.Selectors[0].AttributeRouteModel = new AttributeRouteModel()
{
Template = template
};
}
}
}
調試代碼發現這種方式只在程序第一次運行的時候會執行,之后不會再執行多次,因此效率很高。