首頁 > 軟體

.NET實現API版本控制

2022-07-06 18:00:38

1. 優點

  • 有助於保護原有系統,不受影響,並及時修改問題
  • 可以實現使用者的私人客製化(比如是付費介面)
  • 快速迭代

2. API版本控制

  • 在URL中追加版本或者作為查詢字串引數
  • 通過自動以檔頭和通過接受檔頭

2.1 安裝元件

ASP.NET API versioning為您提供了一種功能強大但易於使用的方法,用於將API版本控制語意新增到使用ASP.NET構建的新的和現有的REST服務中。API版本控制擴充套件定義了簡單的後設資料屬性和約定,用於描述您的服務實現了哪些API版本。

    <PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="4.2.0" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer" Version="4.2.0" />

2.1.1 常用設定

[ApiVersion("1.1")] //設定版本號
[ApiVersionNeutral]//退出版本控制
[MapToApiVersion("1.1")] //設定獨立版本
[ApiVersion("1.0", Deprecated = true)]//api版本已經被棄用
HttpContext.GetRequestedApiVersion().ToString(); //存取版本資訊 

2.2 QueryString來實現版本控制

2.2.1 ConfigureServices中設定

            //Versioning用來實現API的版本控制
            services.AddApiVersioning(options =>
            {
                options.DefaultApiVersion = new ApiVersion(1, 1);//預設版本號
                options.AssumeDefaultVersionWhenUnspecified = true;//此選項將用於不提供版本的請求,預設情況下假定API的版本為1.0
                options.ReportApiVersions = true;//當設定為true時候,api將返回響應檔頭中支援的版本資訊
                //下面這句預設不寫也可以
                //options.ApiVersionReader = new QueryStringApiVersionReader(parameterNames: "api-version");//該名稱用於查詢時候使用
            });

2.2.2 控制器設定版本

namespace NetCore_SwaggerVersion.Controllers.v1
{
    /// <summary>
    /// 版本1.1
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    [ApiVersion("1.1")]//可以設定多個
    [ApiVersion("1.2")]
    public class TestController : ControllerBase
    
namespace NetCore_SwaggerVersion.Controllers.v2
{
    /// <summary>
    /// 版本2.0
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    [ApiVersion("2.6")]
    public class TestController : ControllerBase

不同名稱空間下可以存在相同的控制器

2.2.3 特定方法設定版本

[MapToApiVersion("1.1")]
[HttpGet]
public IEnumerable<string> Get()

2.2.4 設定不受版本控制

    [ApiVersionNeutral]//退出版本控制
    [ApiController]
    [Route("api/[controller]/[action]")]
    public class WeatherForecastController : ControllerBase

2.3.5 存取地址

http://localhost:5000/api/WeatherForecast/Get //不寫版本號的話走的是預設的版本號
http://localhost:5000/api/Test?api-version=1.1
http://localhost:5000/api/Test?api-version=1.2
http://localhost:5000/api/Test?api-version=2.6

2.3 URL Path Segment來實現版本控制

2.3.1 ConfigureServices中設定

            //Versioning用來實現API的版本控制
            services.AddApiVersioning(options =>
            {
                options.DefaultApiVersion = new ApiVersion(1, 1);//預設版本號
                options.AssumeDefaultVersionWhenUnspecified = true;//此選項將用於不提供版本的請求,預設情況下假定API的版本為1.0
                options.ReportApiVersions = true;//當設定為true時候,api將返回響應檔頭中支援的版本資訊
            });

2.3.2 控制器設定版本

namespace NetCore_SwaggerVersion.Controllers.v1
{
    /// <summary>
    /// 版本1.1
    /// </summary>
    [Route("api/v{version:apiVersion}/[controller]")]
    [ApiController]
    [ApiVersion("1.0")]
    [ApiVersion("1.1")]//定義控制器提供哪個版本的API
    public class TestController : ControllerBase
    
namespace NetCore_SwaggerVersion.Controllers.v2
{
    /// <summary>
    /// 版本2.0
    /// </summary>
    [Route("api/v{version:apiVersion}/[controller]")]
    [ApiController]
    [ApiVersion("2.6")]
    public class TestController : ControllerBase

不同名稱空間下可以存在相同的控制器

2.3.3 特定方法設定版本

[MapToApiVersion("1.1")]
[HttpGet]
public IEnumerable<string> Get()

2.3.4 設定不受版本控制

    [ApiVersionNeutral]//退出版本控制
    [ApiController]
    [Route("api/[controller]/[action]")]
    public class WeatherForecastController : ControllerBase

2.3.5 存取地址

http://localhost:5000/api/v1.0/Test
http://localhost:5000/api/v1.1/Test
http://localhost:5000/api/v2.6/Test
http://localhost:5000/api/WeatherForecast/Get 不受版本控制

2.4 HTTP Headers來實現版本控制

2.4.1 ConfigureServices中設定

            //Versioning用來實現API的版本控制
            services.AddApiVersioning(options =>
            {
                options.DefaultApiVersion = new ApiVersion(1, 1);//預設版本號
                options.AssumeDefaultVersionWhenUnspecified = true;//此選項將用於不提供版本的請求,預設情況下假定API的版本為1.0
                options.ReportApiVersions = true;//當設定為true時候,api將返回響應檔頭中支援的版本資訊
                //header傳遞版本資訊
                options.ApiVersionReader = new HeaderApiVersionReader("version");
                options.ApiVersionSelector = new CurrentImplementationApiVersionSelector(options);//如果沒有傳輸版本號,那麼會使用最大版本號  LowestImplementedApiVersionSelector是最小版本號
                options.UseApiBehavior = false;//是否使用API行為
            });

2.4.2 控制器設定版本

namespace NetCore_SwaggerVersion.Controllers.v1
{
    /// <summary>
    /// 版本1.1
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    [ApiVersion("1.1")]//定義控制器提供哪個版本的API
    public class TestController : ControllerBase
    
namespace NetCore_SwaggerVersion.Controllers.v2
{
    /// <summary>
    /// 版本2.0
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    [ApiVersion("2.6")]
    public class TestController : ControllerBase

不同名稱空間下可以存在相同的控制器

2.4.3 特定方法設定版本

[MapToApiVersion("1.1")]
[HttpGet]
public IEnumerable<string> Get()

2.4.4 設定不受版本控制

    [ApiVersionNeutral]//退出版本控制
    [ApiController]
    [Route("api/[controller]/[action]")]
    public class WeatherForecastController : ControllerBase

2.4.5 存取地址

http://localhost:5000/api/Test  //需要在headers裡面增加 version: 1.1
http://localhost:5000/api/WeatherForecast/Get 不受版本控制

2.5 同時支援多種模式

services.AddApiVersioning(o =>
{
    o.ReportApiVersions = true;
    o.AssumeDefaultVersionWhenUnspecified = true;
    o.DefaultApiVersion = new ApiVersion(1, 0);
    o.ApiVersionReader = ApiVersionReader.Combine(new HeaderApiVersionReader("api-version"), new QueryStringApiVersionReader("api-version"));
    //或者
    //同時支援查詢字串和檔頭
    o.ApiVersionReader = new QueryStringOrHeaderApiVersionReader(parameterName: "version"){HeaderNames = { "api-version", "x-ms-version" }}
});

2.6 不借助包,封裝檔案

    public class NameSpaceVersionRoutingConvention:IApplicationModelConvention
    {
        private readonly string apiPrefix;
        private const string urlTemplate = "{0}/{1}/{2}";
        public NameSpaceVersionRoutingConvention(string apiPrefix = "api")
        {
            this.apiPrefix = apiPrefix;
        }

        public void Apply(ApplicationModel application)
        {
            foreach (var controller in application.Controllers)
            {

                var hasRouteAttribute = controller.Selectors
                .Any(x => x.AttributeRouteModel != null);
                if (!hasRouteAttribute)
                {
                    continue;
                }
                var nameSpaces = controller.ControllerType.Namespace.Split('.');
                //獲取namespace中版本號部分
                var version = nameSpaces.FirstOrDefault(x => Regex.IsMatch(x, @"^v(d+)$"));
                if (string.IsNullOrEmpty(version))
                {
                    continue;
                }
                string template = string.Format(urlTemplate, apiPrefix, version,
                controller.ControllerName);
                controller.Selectors[0].AttributeRouteModel = new AttributeRouteModel()
                {
                    Template = template
                };
            }
        }
    }

偵錯程式碼發現這種方式只在程式第一次執行的時候會執行,之後不會再執行多次,因此效率很高。

到此這篇關於.NET實現API版本控制的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com