ASP.NET Core API版本控制

場景:

任何不斷髮展變化的API都需要API版本控制策略。你的API版本可以適應根據API使用者的期望而切換不同版本變得有所不同。我通常建議將以下API版本控制策略作爲整體API管理系統的一部分。

1.如果你的API處於早期測試版本中,爲了獲得消費者的反饋,請建立您的API可能會發生變化的正確期望。在此階段內,你會保留這個版本一段時間,因爲你的API設計可能還會更改。作爲消費者,API是不穩定的,因此他們應該預期到可能會發生的變化。

2.一旦發佈,你的API應被視爲契約,如果沒有新版本,則不能被替換。

3.不間斷的更改會導致次要版本出現問題,客戶端會自動遷移到最新版本,不會出現任何負面副作用。

4.突破性的變化意味着客戶必須遷移到此新版本,因爲它包含一個或多個重大更改。你必須與API使用者建立適當的時間表並定期溝通,以確保他們能方便地遷移到新版本。但在某些情況下,這可能無法馬上實現,所以你的團隊將會被要求暫時性支持以前的API版本。

實現API版本控制的方法

Install-Package Microsoft.AspNetCore.Mvc.Versioning

在 Startup 的 ConfigureServices 中增加一下配置。然後在Configure方法添加app.UseApiVersioning();

  services.AddApiVersioning(o =>
            {
                //在請求響應標頭(Header)中返回所有的版本信息(默認爲api-supported-versions:1.0,2.0,3.0),可以在下面ApiVersionReader中自定義替代參數名稱
                o.ReportApiVersions = true;
                //此選項將用於不提供版本的請求。默認情況下, 假定的 API 版本爲1.0
                o.AssumeDefaultVersionWhenUnspecified = true;
                //缺省api版本號,支持時間或數字版本號
                o.DefaultApiVersion = new ApiVersion(1, 0);
                //支持MediaType、Header、QueryString 設置版本號;缺省爲QueryString、UrlSegment設置版本號
                o.ApiVersionReader = ApiVersionReader.Combine(
                  new MediaTypeApiVersionReader("api-version"),
                  new HeaderApiVersionReader("api-version"),                  
new QueryStringApiVersionReader("api-version"), new UrlSegmentApiVersionReader()); });

 其他參數:

o.ApiVersionSelector可以設置四種值來確定選擇版本的策略

DefaultApiVersionSelector如果請求中沒有指定,則選擇默認版本
CurrentImplementationApiVersionSelector如果請求中沒有指定,則選擇最新的 api 版本
LowestImplementedApiVersionSelector如果請求中沒有指定,則選擇最低的 api 版本
ConstantApiVersionSelector不管請求是否指定, 一直選擇在構造函數中傳遞的常量 api 版本

o.ErrorResponses設置版本匹配錯誤時返回的響應信息

o.RegisterMiddleware默認爲true,可以省略在Configure方法添加app.UseApiVersioning();的代碼

如果控制器不應用[ApiController]的話,需要設置o.UseApiBehavior = false;才能正常工作

(1)通過QueryString進行版本控制

分別在兩個不同的Controller中添加一個獲取版本信息的接口

namespace version.Controllers.v1
{
    [ApiVersion("1.0")]
    [ApiController]
    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
        [HttpGet("version")]
        public string Version() => (HttpContext.GetRequestedApiVersion().ToString());
    }
}
namespace version.Controllers.v2
{
    [ApiVersion("2.0")]
    [ApiController]
    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
        [HttpGet("version")]
        public string Version() => (HttpContext.GetRequestedApiVersion().ToString());
    }
}

 HttpContext.GetRequestedApiVersion().ToString() 是用於獲取請求接口的版本信息。

通過URL Path進行版本控制

一般在Api開發中不會去QueryString的方式去進行版本控制,而是使用URL路徑段的方式來控制版本。

修改兩個Controller中的代碼如下。

namespace version.Controllers.v1
{
    [ApiVersion("1.0")]
    [ApiController]
    [Route("api/v{version:ApiVersion}/[controller]")]
    public class ValuesController : Controller
    {
        [HttpGet("version")]
        public string Version() => (HttpContext.GetRequestedApiVersion().ToString());
    }
}
namespace version.Controllers.v2
{
    [ApiVersion("2.0")]
    [ApiController]
    [Route("api/v{version:ApiVersion}/[controller]")]
    public class ValuesController : Controller
    {
        [HttpGet("version")]
        public string Version() => (HttpContext.GetRequestedApiVersion().ToString());
    }
}

不能像QueryString一樣調用默認的Api版本,因爲URL Path的方式不允許隱式匹配設置的默認Api版本。所以必須申明所有的Api版本。且在請求Api同時必須帶上Api版本號。

[Route("api/v{version:ApiVersion}/[controller]")]中的ApiVersion可以通過o.RouteConstraintName = "ApiName";自定義

 

通過Media Type進行版本控制

我們還可以使用content-type來實現版本的控制

分別修改兩個Controller

namespace version.Controllers.v1
{
    [ApiVersion("1.0")]
    [ApiController]
    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
        [HttpGet("version")]
        public string Version() => (HttpContext.GetRequestedApiVersion().ToString());
    }
}
namespace version.Controllers.v2
{
    [ApiVersion("2.0",Deprecated = true)]
    [ApiController]
    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
        [HttpGet("version")]
        public string Version() => (HttpContext.GetRequestedApiVersion().ToString());
    }
}
訪問時添加content-type:application/json;v=2.0
Deprecated = true表示API已過時
如果應用[ApiVersionNeutral]則表示此Controller或Action不需要版本控制


MapToApiVersion 用法舉例
[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("1")]
[ApiVersion("3")]
public class ValuesController : Controller
{
    [HttpGet]
    public IEnumerable<string> Get1()
    {
        return new string[] {};
    }
 
    [HttpGet, MapToApiVersion("2"), MapToApiVersion("4")]
    public IEnumerable<string> Get2()
    {
        return new string[] {};
    }
 
    [HttpGet, MapToApiVersion("5")]
    public IEnumerable<string> Get3()
    {
        return new string[] {};
    }
}

Get1支持的版本是:1、3;
Get2支持的版本是:2、4;
Get3支持的版本是:5。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章