使用.NET 6開發TodoList應用(21)——實現API版本控制
系列導航及原始碼
需求
API介面版本管理,對於一些規模稍大的企業應用來說,是經常需要關注的一大需求。儘管我們的示例程式TodoList很簡單,但是我們也可以通過這個應用程式,來實踐一下如何管理API介面版本。
目標
實現API介面版本管理。
原理與思路
要實現API版本管理,我們需要這個庫:Microsoft.AspNetCore.Mvc.Versioning
。它提供了.NET Web專案介面的版本管理功能。
實現
新增Nuget Package並配置服務
向Api
專案中新增Microsoft.AspNetCore.Mvc.Versioning
ApiServiceExtensions.cs
using Microsoft.AspNetCore.Mvc; namespace TodoList.Api.Extensions; public static class ApiServiceExtensions { public static void ConfigureApiVersioning(this IServiceCollection services) { services.AddApiVersioning(options => { // 向響應頭中新增API版本資訊 options.ReportApiVersions = true; // 如果客戶端不顯式指定API版本,則使用預設版本 options.AssumeDefaultVersionWhenUnspecified = true; // 配置預設版本為1.0 options.DefaultApiVersion = new ApiVersion(1, 0); }); } }
在Program
中呼叫:
Program.cs
// 省略其他...
builder.ConfigureLog();
builder.Services.ConfigureApiVersioning();
實現API版本控制
方法1: 新增ApiVersion
屬性
我們複製一份TodoItemController
到新檔案TodoItemV2Controller
並修改類名和建構函式,其他保持原樣。為了給Controller標記對應的API版本號,我們分別向兩個Controller上新增屬性:
[ApiVersion("2.0")] [Route("/todo-item")] [ApiController] public class TodoItemV2Controller : ControllerBase { private readonly IMediator _mediator; // 省略其他... }
以及
[ApiVersion("1.0")]
[Route("/todo-item")]
[ApiController]
public class TodoItemController : ControllerBase
{
private readonly IMediator _mediator;
// 省略其他..
}
驗證1: 請求中不新增任何API版本相關欄位
啟動Api
專案,執行查詢TodoItem
的請求:
- 請求
-** 響應**
日誌輸出:
結果返回:
以及響應頭資訊中包含的api-supported-versions
:
驗證2: 請求中新增查詢字串api-version
啟動Api
專案,執行查詢TodoItem
的請求:
-
請求
-
響應
日誌輸出:
結果返回(可以自己嘗試修改內部邏輯,這裡我懶了沒改實現,不過從日誌已經能看出請求確實進入了V2版本的Controller):
以及響應頭資訊中包含的api-supported-versions
:
方法2: 通過請求頭攜帶API版本資訊
為了實現這一點,需要在ConfigureApiVersioning
中增加配置:
ApiServiceExtensions.cs
// 省略其他...
// 指定請求頭中攜帶用於指定API版本資訊的欄位
options.ApiVersionReader = new HeaderApiVersionReader("api-version");
驗證3: 通過請求頭攜帶API版本資訊
啟動Api
專案,執行查詢TodoItem
的請求:
-
請求
-
響應
日誌輸出:
返回結果就不繼續貼了,以及響應頭資訊中包含的api-supported-versions
:
方法3: 通過URL路徑訪問對應的版本
除了這種之外的以上幾種方法,都不需要修改介面的URI,而這種方式需要修改URI路徑。我們在兩個Controller上修改URI如下:
[ApiVersion("2.0")]
[Route("/{v:apiVersion}/todo-item")]
[ApiController]
// 省略其他...
驗證4: 通過URI路徑選擇API版本
啟動Api
專案,執行查詢TodoItem
的請求:
-
請求
-
響應
日誌輸出:
返回結果就不繼續貼了,以及響應頭資訊中包含的api-supported-versions
:
一點擴充套件
有的時候我們需要標記一個版本的請求為deprecated
,但是還不想完全刪除這個Controller,可以用下面的方式進行標記,這樣返回頭中會指出這個版本的API已經處於deprecated
狀態了。
[ApiVersion("2.0", Deprecated = true)]
[Route("/{v:apiVersion}/todo-item")]
[ApiController]
// 省略其他...
或者在ConfigureApiVersioning
中使用Convention進行標記:
// 省略其他...
// 使用Convention標記deprecated
options.Conventions.Controller<TodoItemV2Controller>().HasDeprecatedApiVersion(new ApiVersion(2, 0));
我們再請求2.0版本的API時,仍然可以獲取資料,但是得到的返回頭中資訊如下:
對比使用Convention方式標記的返回頭:
總結
在本文中我們使用多種方式實現了管理API版本的需求,可以根據具體的需要選擇一種進行實現。下一篇我們介紹關於響應的快取實現。