1. 程式人生 > >ASP.Net Core WebApi幾種版本控制對比

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

 一、版本控制的好處:

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

(2)它還可以幫助為選定的客戶提供額外的功能。

API 版本控制可以採用不同的方式進行控制,方法如下:

(1) URL 中追加版本或作為查詢字串引數,

(2)通過自定義標頭和通過接受標頭

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

一、建立asp.net core webapi 專案,引用NuGet包:Install-Package Microsoft.AspNetCore.Mvc.Versioning -Version 2.0.0

 

 

專案和安裝包都好了,接著我們需要在Startup.cs中的

ConfigureServices 方法中新增下面的程式碼:

 

如您所見, 配置了3不同的選項。

  •  ReportAPIVersions: 這是可選的。但是, 當設定為 true , API 將返回響應標頭中支援的版本資訊。
  •  AssumeDefaultVersionWhenUnspecified: 此選項將用於不提供版本的請求。預設情況下, 假定的 API 版本為1.0
  • DefaultApiVersion: 此選項用於指定在請求中未指定版本時要使用的預設 API 版本。這將預設版本為1.0

這是所有的配置和設定。現在, 我們將看到訪問 API 版本的不同方式。

二、通過

QueryString來實現版本控制

開啟我們的控制器,在上面新增ApiVersion特性,如下程式碼所示:

上面的程式碼作為1.0版本。您還可以在不同的名稱空間中建立另一個具有相同名稱的控制器類, 並將 API 版本設定為2.0版本。如下圖所示:

 

就這樣。現在轉到瀏覽器並訪問控制器。您應該看到 API 版本1.0 控制器的輸出, 因為它被設定為預設值。現在在 URL 中追加 api-version=2, 您應該看到 api 版本2.0 控制器的輸出。

二、通過URL Path Segment來實現:

查詢字串引數很有用, 但在長 URL 和其他查詢字串引數的情況下可能會很痛苦。相反

, 更好的方法是在 URL 路徑中新增版本。比如:

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

還是上面的專案,只不過需要在v1v2控制器中加入,下面的程式碼。如下圖所示:

同樣, 您需要將路由引數更新到所有適用的位置。使用此更改, 在訪問API 介面時總是需要有版本號。您可以通過 api/v1/values 訪問到版本 1.0, 通過api/v2/values 訪問版本 2.0, 更改 URL 中的版本號。簡單, 看起來更乾淨了。

測試結果如下:

三、通過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的版本控制,方法是有的,不賣關子了,大家接著往下看。

四、終極版本(不借助任何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     }

除錯程式碼發現這種方式只在程式第一次執行的時候會執行,之後不會再執行多次,因此效率很高。

五、總結:

通過上面兩種版本控制的實現和對比,我更偏向通過第三方的包來實現版本控制,這種方法功能更強大。這純屬於個人愛好了,大家可以根據不同的場景來決定使用哪種方式來實現,好了講到這裡,謝謝,希望對你有幫助。

覺得可以的話,希望點下推薦哈~你們的推薦是我的動力。

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

作者:郭崢

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

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連結。