ASP.Net Core WebApi幾種版本控制對比

 1、版本控制的好處:

(1)有助於及時推出功能, 而不會破壞現有系統。web

(2)它還能夠幫助爲選定的客戶提供額外的功能。api

API 版本控制能夠採用不一樣的方式進行控制,方法以下:瀏覽器

(1)在 URL 中追加版本或做爲查詢字符串參數,app

(2)經過自定義標頭和經過接受標頭asp.net

在這篇文章中, 讓咱們來看看如何支持多個版本的 ASP.NET  Core  Web API。函數

1、建立asp.net core webapi 項目,引用NuGet包:Install-Package Microsoft.AspNetCore.Mvc.Versioning -Version 2.0.0post

 

 

項目和安裝包都好了,接着咱們須要在Startup.cs中的ConfigureServices 方法中添加下面的代碼:測試

 

 

如您所見, 配置了3不一樣的選項。this

  •  ReportAPIVersions: 這是可選的。可是, 當設置爲 true 時, API 將返回響應標頭中支持的版本信息。
  •  AssumeDefaultVersionWhenUnspecified: 此選項將用於不提供版本的請求。默認狀況下, 假定的 API 版本爲1.0。
  • DefaultApiVersion: 此選項用於指定在請求中未指定版本時要使用的默認 API 版本。這將默認版本爲1.0。

這是全部的配置和設置。如今, 咱們將看到訪問 API 版本的不一樣方式。url

 

2、經過QueryString來實現版本控制

打開咱們的控制器,在上面添加ApiVersion特性,以下代碼所示:

上面的代碼做爲1.0版本。您還能夠在不一樣的命名空間中建立另外一個具備相同名稱的控制器類, 並將 API 版本設置爲2.0版本。以下圖所示:

 

就這樣。如今轉到瀏覽器並訪問控制器。您應該看到 API 版本1.0 控制器的輸出, 由於它被設置爲默認值。如今在 URL 中追加 api-version=2, 您應該看到 api版本2.0 控制器的輸出。

2、經過URL Path Segment來實現:

查詢字符串參數頗有用, 但在長 URL 和其餘查詢字符串參數的狀況下可能會很痛苦。相反, 更好的方法是在 URL 路徑中添加版本。好比:

  • api/v1/values
  • api/v2/values

仍是上面的項目,只不過須要在v1和v2控制器中加入,下面的代碼。以下圖所示:

一樣, 您須要將路由參數更新到全部適用的位置。使用此更改, 在訪問API 接口時老是須要有版本號。您能夠經過 api/v1/values 訪問到版本 1.0, 經過api/v2/values 訪問版本 2.0, 更改 URL 中的版本號。簡單, 看起來更乾淨了。

測試結果以下:

3、經過HTTP Headers來實現版本控制

在上述兩種方法中, 須要修改 URL 以支持版本控制。可是, 若是您但願 api 的URL 保持乾淨, 則 api 版本信息也能夠經過附加 HTTP 報頭來傳遞。要進行此工做,您須要配置 ApiVersionReader 選項。代碼以下:

 

 

 

突出顯示的行告訴咱們header  "api-version" 如今是 api 版本號的預期位置。確保路由屬性沒有版本詳細信息。因此測試它,結果以下:

當您將2.0 做爲值提供給 "api 版本" 時, 它將調用版本2.0 控制器並返回輸出。

簡單, 易於設置。可是, 如今查詢字符串參數的方法進行版本控制將不起做用。一旦設置了header, 就不能指定查詢字符串參數。若是您但願支持這兩種狀況, 而不是 HeaderApiVersionReader, 請使用 QueryStringOrHeaderApiVersionReader。代碼以下:

 

所以, 如今支持查詢字符串參數和header。默認查詢字符串參數名稱是 api-version, 所以您能夠將構造函數留空, 但若是須要其餘名稱, 則須要提供。您還能夠對查詢字符串參數和標頭使用有不一樣的名稱。請記住, 咱們還將 ReportApiVersions 設置爲 true, 該值返回響應標頭中的版本信息。見下圖。

 

如今, 讓咱們來看看另外幾個選項。

MapToApiVersion參數的用法:

MapToApiVersion 屬性容許將單個 API 操做映射到任何版本。換言之, 一個支持多個版本的單控制器。控制器可能只有版本3支持的 API 操做方法。在這種狀況下, 您可使用 MapToApiVersion。看看下面的代碼。

上面代碼的意思是:public string Get()該方法只有在版本1.0中支持,public string Getv3()方法只有在版本3.0中支持。

有圖有真像,很靈活,我很喜歡。

Deprecated參數的用法:

當支持多個 API 版本時, 某些版本最終會隨着時間的推移而被棄用。要標記一個或多個 api 版本已被廢棄, 只需用Deprecated修飾您的控制器。這並不意味着不支持 API 版本。你仍然能夠調用該版本。它只是一種讓 調用API 用戶意識到如下版本在未來會被棄用。

上面把Deprecated設置爲TRUE表示,版本1.0未來會被棄用。訪問咱們的API接口,能夠在響應頭中能夠看到,下面信息,以下圖所示:

ApiVersionNeutral特性的使用:

ApiVersionNeutral 特性定義此 API 不在支持版本控制。不管 支持api 版本控制或不支持 api 版本控制的舊式 api,這對於行爲徹底相同的 api 很是有用。所以, 您能夠添加 ApiVersionNeutral 屬性以從版本控制中退出。

獲取版本信息(Version Information)

若是你想知道那個版本的客戶端在被訪問,你能夠經過下面的代碼實現該功能:

綜上所述, 具備多個版本的 API 能夠幫助以一種有效的方式推出加強的功能, 同時也便於跟蹤更改。在這篇文章中, 咱們看到了如何在 ASP.NET  core WEB API 中添加對多個版本的支持。nuget 包支持經過查詢字符串參數進行版本控制, 在 URL 中添加路徑段和經過標頭。它還具備版本單一 API 操做和從版本中選擇退出的功能。

能不能不借助第三方的包來實現一個API的版本控制,方法是有的,不賣關子了,你們接着往下看。

 

4、終極版本(不借助任何NuGet包)asp.net core web api版本控制

新建一個core API項目:

 

在VersionControl文件夾下面,新建一個實現了IApplicationModelConvention接口的類NameSpaceVersionRoutingConvention   代碼以下:

 

複製代碼
 1  public class NameSpaceVersionRoutingConvention:IApplicationModelConvention
 2     {
 3         private readonly string apiPrefix;
 4         private const string urlTemplate = "{0}/{1}/{2}";
 5         public NameSpaceVersionRoutingConvention(string apiPrefix = "api")
 6         {
 7             this.apiPrefix = apiPrefix;
 8         }
 9 
10         public void Apply(ApplicationModel application)
11         {
12             foreach (var controller in application.Controllers)
13             {
14                 
15                 var hasRouteAttribute = controller.Selectors
16                 .Any(x => x.AttributeRouteModel != null);
17                 if (!hasRouteAttribute)
18                 {
19                     continue;
20                 }
21                 var nameSpaces = controller.ControllerType.Namespace.Split('.');
22                 //獲取namespace中版本號部分
23                 var version = nameSpaces.FirstOrDefault(x => Regex.IsMatch(x, @"^v(\d+)$"));
24                 if (string.IsNullOrEmpty(version))
25                 {
26                     continue;
27                 }
28                 string template = string.Format(urlTemplate, apiPrefix, version,
29                 controller.ControllerName);
30                 controller.Selectors[0].AttributeRouteModel = new AttributeRouteModel()
31                 {
32                     Template = template
33                 };
34             }
35         }
36     }
複製代碼

 

調試代碼發現這種方式只在程序第一次運行的時候會執行,以後不會再執行屢次,所以效率很高。

5、總結:

經過上面兩種版本控制的實現和對比,我更偏向經過第三方的包來實現版本控制,這種方法功能更強大。這純屬於我的愛好了,你們能夠根據不一樣的場景來決定使用哪一種方式來實現,好了講到這裏,謝謝,但願對你有幫助。

以爲能夠的話,但願點下推薦哈~大家的推薦是個人動力。

 

多謝@光陰四濺 及時指出個人錯誤,很感謝!

代碼下載地址:WebApiVersionControl.rar

做者:郭崢

出處:http://www.cnblogs.com/runningsmallguo/

本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文連接。

相關文章
相關標籤/搜索