實作 Web API Versioning 功能

09/12 更新

Kodofish
8 min readSep 11, 2017
今天才發現如果你的Web API 專案有使用 Route Attribute 的話,SDammann.WebApi.Versioning 在取得 API 資訊會有錯誤。在 github 上這個 Issue 仍未被解決…Orz

有開發 Web API 給 App 串接的專案一定都會遇到一個問題,就是當 Web API 更新時,如何 App 在尚未更新時能夠繼續使用原有的 Web API 而不受影響?

而Developer 又能夠簡單輕易的實作不同版本的 Web API ?

方法有許多種,其中一種就是實作 Web API Versioning。

在 github.com 上有個 OpenSource:SDammann.WebApi.Versioning,就可以讓我們快速的開發 Web API Versioning 功能。

從專案首頁就可以清楚這OpenSource 可以實作四種Versioning。

  1. Routing Version
  2. Version Header Versioned
  3. Accept Header Versioned
  4. Accept Header

Routing Versioned

使用這方式可以直接透過 API Routing 就可以達到 Versioning 的需求,API 版本號碼會顯示在 URL 上,例如:

http://example.com/api/v1/values

用這種方式除了在 Url 上會顯示出版本號碼外,Routing 也會因此而越來越複雜,必須適時的縮減版本。

Version Header Versioned

這方式是需要在 Request Header 加上「X-Api-Version」的 Http header,就可以決定所要使用的版本。例如:

X-Api-Version:2

用數字即可用來決定所要呼叫的版本。

Accept Header Versioned

透過「Accept」Http header 來決定所使用的版本,「Accept」內容可能會像是:

application/vnd.company.myapp-v3+json

Accept Header

這方式與前一個「Accept Header Versioned」很類似,一樣是透過「Accept」來決定所使用的版本,但內容上就比較簡單一點,直接在內容裡加上「Version=1」就可以決定版本了,內容像是

application/json; version=1

選擇實作方式

由於工作中所開發的 Web API 專案己經 Release 給 Mobile Team 進行開發了,不想讓 Mobile Team 因此要修改呼叫的 Url,只能選擇在 Http header上做手腳,但又不想在「Accept」上做處理,又要考量到若沒有在 Header 上帶入版本號碼時,要能夠設定預設版本,因此決定使用 Version Header Versioned

建立專案並安裝所需要的套件

首先先建立一個 Web API 專案,並且透過 Nuget 安裝Autofac、Swashbuckle、SDammann.WebApi.Versioning 這三個套件。

建立不同版本 ApiController

接下來在 Controllers 目錄建立三個資料夾,並在資料夾內建立相同名稱的ApiController,故意讓回傳不同的 Model。

透過 Autofac 進行 Controller 及相關物件的注入

由於工作中的專案是使用 Autofac 來做 DI 的,因此這裡也使用 Autofac 來注入必須使用的 Class。這裡重點是在第20及21行,必須要註冊 VersionApiExplorer及VersionHeaderVersionedControllerSelector這兩個 class。

在註冊 VersionHeaderVersionedControllerSelector 時,必須設定「defaultVersion」給予預設的版本號,以應付 http request 沒有帶 header 時,自動轉到預設 Controller 執行。

Postman進行測試

做到這裡就可以用 Postman 來進行測試,看看 Versioning 功能是否能夠正確執行。

用 Postman 測試執行 Version 1。

正確執行 Version 1

再用 Postman 測試執行 Version 2。

Version 2 也沒問題

如果有子版本號碼呢?

子版本號碼也沒問題

用 Swagger 寫文件

寫 Web API 很多人都會用 Swagger 來作用 Web Api 的文件,另外也能夠方便使用者直接用 Swagger 進行 Api 測試。那 Swagger 如何能夠顯示多版本 Web API 呢?

啟用 MultipleApiVersions 功能

在 SwaggerConfig.cs 裡可以啟用 MultipleApiVersions 的功能。在這裡可以透過

public void MultipleApiVersions(Func<ApiDescription, string, bool> versionSupportResolver, Action<VersionInfoBuilder> configure);

這個界面來提供 Versioning 邏輯,讓 Swagger 可以判斷 Controller 各別屬於那一個版本,Swagger 才能顯示正確的 Api 描述在網頁上。

versionSupportResolver 要傳入 Versioning 判斷還輯。

configure 則是要傳入有那些 Api 版本資料,範例如下:

添加 header 值

做到這裡 Swagger 就可以正確顯示 Controller 版本並且使用 Swagger 進行API 呼叫測試。

但不論切換到那個版本,似乎都是呼叫 Version 2 的版本。

怎麼呼叫都是呼叫到 Version 2 的 Controller

看了一下 Curl 發現裡頭並沒有帶入「X-Api-Version」的 Header,這邊得手動修改一下 Swagger,讓它自己產生出「X-Api-Version」才行。

實作 OperationFilter

Swagger 可以透過繼承 IOperationFilter 來實作一個 OperaionFilter,在這個OperationFilter 可以取得 Controller 的 NameSpace,用它來判斷所呼叫的Api Version 為何,然後再將 Api Version 加到 Header 裡,就完成了。

最後在 SwaggerConfig.cs 裡注入剛剛新增的 OperationFilter。完整 SwaggerCofnig.cs 範例如下:

完成

這樣就可以透過 Swagger 呼叫不同版本的 API 囉。

相關資料

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Kodofish
Kodofish

Written by Kodofish

從學生時就熱愛寫程式,第一份工作就在台灣500大企業的遊戲公司擔任軟體開發工程師,職涯中曾任 Team lead、PM、經理的管理職務,現在是某軟體公司的資深後端工程師。自從 2012 年接觸了 Agile 後,發現自己其實是個持續學習者並樂此不疲。

No responses yet

Write a response