使用.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的請求:

  • 請求
    image

-** 響應**
日志輸出:
image
結果返回:
image
以及響應頭信息中包含的api-supported-versions
image

驗證2: 請求中添加查詢字符串api-version

啟動Api項目,執行查詢TodoItem的請求:

  • 請求
    image

  • 響應
    日志輸出:
    image
    結果返回(可以自己嘗試修改內部邏輯,這里我懶了沒改實現,不過從日志已經能看出請求確實進入了V2版本的Controller):
    image
    以及響應頭信息中包含的api-supported-versions
    image

方法2: 通過請求頭攜帶API版本信息

為了實現這一點,需要在ConfigureApiVersioning中增加配置:

  • ApiServiceExtensions.cs
// 省略其他...
// 指定請求頭中攜帶用於指定API版本信息的字段
options.ApiVersionReader = new HeaderApiVersionReader("api-version");
驗證3: 通過請求頭攜帶API版本信息

啟動Api項目,執行查詢TodoItem的請求:

  • 請求
    image

  • 響應
    日志輸出:
    image
    返回結果就不繼續貼了,以及響應頭信息中包含的api-supported-versions
    image

方法3: 通過URL路徑訪問對應的版本

除了這種之外的以上幾種方法,都不需要修改接口的URI,而這種方式需要修改URI路徑。我們在兩個Controller上修改URI如下:

[ApiVersion("2.0")]
[Route("/{v:apiVersion}/todo-item")]
[ApiController]
// 省略其他...
驗證4: 通過URI路徑選擇API版本

啟動Api項目,執行查詢TodoItem的請求:

  • 請求
    image

  • 響應
    日志輸出:
    image
    返回結果就不繼續貼了,以及響應頭信息中包含的api-supported-versions
    image

一點擴展

有的時候我們需要標記一個版本的請求為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時,仍然可以獲取數據,但是得到的返回頭中信息如下:
image
對比使用Convention方式標記的返回頭:
image

總結

在本文中我們使用多種方式實現了管理API版本的需求,可以根據具體的需要選擇一種進行實現。下一篇我們介紹關於響應的緩存實現。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM