.Net Core中的Api版本控制
原文鏈接:API Versioning in .Net Core
作者:Neel Bhatt
簡介
Api的版本控制是Api開發中經常遇到的問題, 在大部分中大型項目都需要使用到Api的版本控制
在本篇博客中,我們將說明一下如何在.Net Core Api項目中使用Api版本控制。
本篇博客中測試項目的開發環境:
- Visual Studio 2017
- .Net Core 2.1 SDK
.Net Core Api中使用Api版本控制
創建一個Api項目
首先我們創建一個.NET Core Api項目
使用Nuget安裝Api版本控制庫
.NET Core Mvc中,微軟官方提供了一個可用的Api版本控制庫Microsoft.AspNetCore.Mvc.Versioning
PM> Install-Package Microsoft.AspNetCore.Mvc.Versioning
修改Startup類
Microsoft.AspNetCore.Mvc.Versioning庫安裝完成之後,下一步我們來添加Api版本控制服務。
這裏我們需要在Startup類的ConfigureService方法中添加以下代碼。
services.AddApiVersioning(o => { o.ReportApiVersions = true; o.AssumeDefaultVersionWhenUnspecified = true; o.DefaultApiVersion = new ApiVersion(1, 0); });
代碼解釋
ReportApiVersion
屬性是一個布爾類型,如果設置為true, 在Api請求的響應頭部,會追加當前Api支持的版本, 例
Response Header
api-supported-versions: 1.0
content-type: application/json; charset=utf-8
date: Sat, 06 Oct 2018 05:24:21 GMT
server: Kestrel
status: 200
x-powered-by: ASP.NET
AssumeDefaultVersionWhenUnspecified
屬性是為了標記當客戶端沒有指定版本號的時候,是否使用默認版本號DefaultApiVersion
屬性即默認版本號
創建多版本Api
這裏為了測試.Net Core Mvc的Api版本控制庫,我們創建如下2個Controller。
[ApiVersion("1.0")]
[Route("api/values")]
[ApiController]
public class ValuesV1Controller : ControllerBase
{
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "Value1 from Version 1", "value2 from Version 1" };
}
}
[ApiVersion("2.0")]
[Route("api/values")]
[ApiController]
public class ValuesV2Controller : ControllerBase
{
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1 from Version 2", "value2 from Version 2" };
}
}
代碼解釋
Value1Controller
和Value2Controller
使用了一樣的路由"/api/values"Value1Controller
類頭部使用ApiVersion
特性標記了當前Controller的Api版本號是1.0Value2Controller
類頭部使用ApiVersion
特性標記了當前Controller的Api版本號是2.0
-Value1Controller
和Value2Controller
都持有相同方法簽名的Get
方法, 只是2個Get
中返回了不同的字符串
現在我們啟動項目,得到的結果如下,說明當沒有指定Api版本號時,項目自動使用1.0版本的Api, 即ValuesV1Controller
中的Get方法。
如何在查詢字符串(Query String)中使用版本控制
Microsoft.AspNetCore.Mvc.Versioning支持以QueryString的形式指定請求Api的版本號。開發人員可以在Url中指定api-version參數來選擇調用的Api版本號。
以當前項目為例
當請求https://localhost:44319/api/values?api-version=2.0時, 返回結果
["value1 from Version 2","value2 from Version 2"]
當請求https://localhost:44319/api/values?api-version=1.0時, 返回結果
["Value1 from Version 1","value2 from Version 1"]
如何使用路由約束中指定請求Api的版本
Microsoft.AspNetCore.Mvc.Versioning還支持使用路由約束指定請求Api的版本號。
例: [Route(“api/{v:apiVersion}/Values”)]
我們對之前2個Controller的代碼作如下修改。
[ApiVersion("1.0")]
[Route("api/{v:apiVersion}/values")]
[ApiController]
public class ValuesV1Controller : ControllerBase
{
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "Value1 from Version 1", "value2 from Version 1" };
}
}
[ApiVersion("2.0")]
[Route("api/{v:apiVersion}/values")]
[ApiController]
public class ValuesV2Controller : ControllerBase
{
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1 from Version 2", "value2 from Version 2" };
}
}
現在我們通過以下2個Url請求Api, 返回的結果如下 :
/api/2.0/values
["value1 from Version 2","value2 from Version 2"]
/api/1.0/values
["Value1 from Version 1","value2 from Version 1"]
如何在請求頭(HTTP Header)中使用版本控制
以上的2種方式需要修改請求的Url, 如果你不喜歡這2種方式,Microsoft.AspNetCore.Mvc.Versioning還提供了第三種指定Api版本號的方式,即在HTTP請求頭中添加版本號參數。
為了啟用這種方式,我們首先需要在Startup.cs中修改Microsoft.AspNetCore.Mvc.Versioning的配置, 代碼如下:
services.AddApiVersioning(o =>
{
o.ReportApiVersions = true;
o.AssumeDefaultVersionWhenUnspecified = true;
o.DefaultApiVersion = new ApiVersion(1, 0);
o.ApiVersionReader = new HeaderApiVersionReader("x-api-version");
});
這裏通過ApiVersionReader
屬性指定了Api版本號是從請求頭部的x-api-version
屬性來的。
Tips: 一旦你使用
o.ApiVersionReader = new HeaderApiVersionReader("x-api-version");
, 在查詢字符串中指定版本號的方式將不再可用,如果你希望同時支持2種方式,請改用o.ApiVersionReader = new QueryStringOrHeaderApiVersionReader("x-api-version");
下面我們通過Postman來請求2.0的Api, 結果正確返回了。
其他特性
棄用Api(Deprecated)特性
有些時候,我們需要標記一些過時的Api為棄用狀態,但是我們又不希望完全移除這個版本的Api, 我們可以使用Deprecated
特性。
例:我們當前希望棄用ValuesV1Controller
, 我們可以指定Deprecated特性的值為true
[ApiVersion("1.0", Deprecated = true)]
[Route("api/values")]
[ApiController]
public class ValuesV1Controller : ControllerBase
{
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "Value1 from Version 1", "value2 from Version 1" };
}
}
當我們請求在此請求這個api的時候, 在響應頭中會出現api-deprecated-versions
和api-supported-versions
2個屬性。
Response Header
api-deprecated-versions: 1.0
api-supported-versions: 2.0
content-type: application/json; charset=utf-8
date: Sat, 06 Oct 2018 06:32:18 GMT
server: Kestrel
status: 200
x-powered-by: ASP.NET
這段響應的意思就是1.0版本的Api已經過期了,2.0版本中有相同的Api, 可以換用2.0版本的Api。
使用ApiVersionNeutral
指定不需要版本控制的Api
在編寫Api的時候,對於一些非常簡單的Api, 我們可能不需要指定Api版本號, 例如健康檢查Api。我們可以使用ApiVersionNeutral
特性,將它從Api版本控制中排除掉。
例:
[ApiVersionNeutral]
[Route("api/[controller]")]
[ApiController]
public class HealthCheckController : ControllerBase
{
public string Get()
{
return "Good";
}
}
本篇源代碼
.Net Core中的Api版本控制