天天看點

Asp.Net.Core WebApi 版本控制

Asp.Net.Core WebApi 版本控制

前言

在後端Api的開發過程中,無法避免的會遇到接口疊代的過程,如何保證新老接口的共存和接口的向前的相容呢,這時候就需要對Api進行版本的控制,那如何優雅的控制Api的版本呢?

開始

Microsoft.AspNetCore.Mvc.Versioning 是一個微軟官方推出的一個用于管理Api版本的包,配置簡單,功能強大。 github位址.

建立一個WebApi項目并通過指令引用包。

Install-Package Microsoft.AspNetCore.Mvc.Versioning

最新版本已經支援Core3.1

項目結構如下

在 Startup 的 ConfigureServices 中增加一下配置。

services.AddApiVersioning(options =>

{

options.ReportApiVersions = true; 
options.AssumeDefaultVersionWhenUnspecified = true; 
options.DefaultApiVersion = new ApiVersion(1, 0);            

});

ReportApiVersions:是否在請求頭中傳回受支援的版本資訊。

AssumeDefaultVersionWhenUnspecified:請求沒有指明版本的情況下是否使用預設的版本。

DefaultApiVersion:預設的版本号。

通過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() 是用于擷取請求接口的版本資訊。

我們通過postman來請求這兩個接口當我們沒有給到具體請求哪個版本的時候會根據在ConfigureServices中配置的預設版本去執行。

指定版本請求結果

在響應頭中會顯示目前支援的所有的Api版本

通過URL Path進行版本控制

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

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

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

通過postman進行測試

可以看到當我們使用指定的版本是可以正常通路的時候,但是如果我們去掉了Api版本号就會抛出404,并不能像QueryString一樣調用預設的Api版本,因為URL Path的方式不允許隐式比對設定的預設Api版本。是以必須申明所有的Api版本。且在請求Api同時必須帶上Api版本号。

通過Media Type進行版本控制

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

修改ConfigureServices中的配置

options.ApiVersionReader = new MediaTypeApiVersionReader();
options.AssumeDefaultVersionWhenUnspecified = true;
options.ApiVersionSelector = new CurrentImplementationApiVersionSelector(options);
           

CurrentImplementationApiVersionSelector 如果沒有在content-type中傳遞Api版本好,将預設比對最新的Api版本

分别修改兩個Controller

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

使用Postman測試

通過自定義Headers進行版本控制

services.AddControllers();

options.ReportApiVersions = true;
options.ApiVersionReader = new HeaderApiVersionReader("api_version");
options.AssumeDefaultVersionWhenUnspecified = true;
options.DefaultApiVersion = new ApiVersion(1, 0);           

api_version 是你Headers中Key的名字。

特性

當哪個Api版本不在更新,就需要棄用掉這個版本。當Deprecated值為true時說明該Api版本已經已經棄用,但是棄用不代表不能請求。隻是會在響應頭中告知次版本已經已經棄用。

[ApiVersion("1.0",Deprecated= true)]
[ApiController]
[Route("api/[controller]")]
public class ValuesController : Controller
{
    [HttpGet("version")]
    public string Version() => (HttpContext.GetRequestedApiVersion().ToString());
}           

項目總有一些功能是不需要版本的控制,是以我們希望它不受版本控制。可以添加[ApiVersionNeutral]特性使Api支援版本控制。

[ApiVersionNeutral]
[ApiController]
[Route("api/[controller]")]
public class ValuesController : Controller
{
    [HttpGet("version")]
    public string Version() => (HttpContext.GetRequestedApiVersion().ToString());
}           

MapToApiVersion 可以将單個Api歸類于任何版本。在一個Controller中可以存在多個版本的Api。我們可以配合Deprecated來靈活的控制我們的Api。

[ApiVersion("3.0")]
[ApiVersion("1.0",Deprecated= true)]
[ApiController]
[Route("api/v{version:ApiVersion}/[controller]")]
public class ValuesController : Controller
{
    [HttpGet("version"), MapToApiVersion("1.0")]
    public string Version() => (HttpContext.GetRequestedApiVersion().ToString());

    [HttpGet("version3"), MapToApiVersion("3.0")]
    public string Version3() => (HttpContext.GetRequestedApiVersion().ToString());
}           

通過postman測試一下。

總結

可以看到Microsoft.AspNetCore.Mvc.Versioning功能還能強大的,基本滿足了大部分的需求,還有一些功能可能沒有在本文中涉及到,可以去這裡.翻閱。

原文位址

https://www.cnblogs.com/linhuiy/p/12668535.html

繼續閱讀