歡迎光臨
每天分享高質量文章

.Net Core中的Api版本控制

作者:LamondLu

連結:https://www.cnblogs.com/lwqlun/p/9747180.html

原文連結:https://neelbhatt.com/2018/04/21/api-versioning-in-net-core/

簡介

Api的版本控制是Api開發中經常遇到的問題, 在大部分中大型專案都需要使用到Api的版本控制

 

在本篇部落格中,我們將說明一下如何在.Net Core Api專案中使用Api版本控制。

 

本篇部落格中測試專案的開發環境:

 

  • Visual Studio 2017

  • .Net Core 2.1 SDK

.Net Core Api中使用Api版本控制

建立一個Api專案

 

首先我們建立一個.NET Core Api項

 

 

使用Nuget安裝Api版本控制庫

 

.NET Core Mvc中,微軟官方提供了一個可用的Api版本控制庫

Microsoft.AspNetCore.Mvc.Versioning。 這裡我們可以使用Nuget安裝這個包。

PM> Install-Package Microsoft.AspNetCore.Mvc.Versioning

修改Startup類

 

Microsoft.AspNetCore.Mvc.Versioning庫安裝完成之後,下一步我們來新增Api版本控制服務。

 

這裡我們需要在Startup類的ConfigureService方法中新增以下程式碼。

    services.AddApiVersioning(o => {
        o.ReportApiVersions = true;
        o.AssumeDefaultVersionWhenUnspecified = true;
        o.DefaultApiVersion = new ApiVersion(10);
    });

 

程式碼解釋

ReportApiVersion屬性是一個布林型別,如果設定為true, 在Api請求的響應頭部,會追加當前Api支援的版本, 例

Response Header
api-supported-versions: 1.0
content-type: application/json; charset=utf-8
date: Sat, 06 Oct 2018 05:24:21 GMT
server: Kestrel
status: 200
x-powered-by: ASP.NET

AssumeDefaultVersionWhenUnspecified屬性是為了標記當客戶端沒有指定版本號的時候,是否使用預設版本號
DefaultApiVersion屬性即預設版本號

建立多版本Api

 

這裡為了測試.Net Core Mvc的Api版本控制庫,我們建立如下2個Controller。

 

    [ApiVersion("1.0")]
    [Route("api/values")]
    [ApiController]
    public class ValuesV1Controller : ControllerBase
    {
        [HttpGet]
        public IEnumerable<stringGet()
        
{
            return new string[] { "Value1 from Version 1""value2 from Version 1" };
        }
    }   

    [ApiVersion("2.0")]
    [Route("api/values")]
    [ApiController]
    public class ValuesV2Controller : ControllerBase
    {
        [HttpGet]
        public IEnumerable<stringGet()
        
{
            return new string[] { "value1 from Version 2""value2 from Version 2" };
        }
    }

程式碼解釋

 

  • Value1Controller和Value2Controller使用了一樣的路由”/api/values”

  • Value1Controller類頭部使用ApiVersion特性標記了當前Controller的Api版本號是1.0

  • Value2Controller類頭部使用ApiVersion特性標記了當前Controller的Api版本號是2.0
    -Value1Controller和Value2Controller都持有相同方法簽名的Get方法, 只是2個Get中傳回了不同的字串

 

現在我們啟動專案,得到的結果如下,說明當沒有指定Api版本號時,專案自動使用1.0版本的Api, 即ValuesV1Controller中的Get方法。

 

 

如何在查詢字串(Query String)中使用版本控制

 

Microsoft.AspNetCore.Mvc.Versioning支援以QueryString的形式指定請求Api的版本號。

開發人員可以在Url中指定api-version引數來選擇呼叫的Api版本號。

 

以當前專案為例


當請求https://localhost:44319/api/values?api-version=2.0時, 傳回結果

 

["value1 from Version 2","value2 from Version 2"]

當請求https://localhost:44319/api/values?api-version=1.0時, 傳回結果

 

["Value1 from Version 1","value2 from Version 1"]

如何使用路由約束中指定請求Api的版本

 

Microsoft.AspNetCore.Mvc.Versioning還支援使用路由約束指定請求Api的版本號。

 

例: [Route(“api/{v:apiVersion}/Values”)]

 

我們對之前2個Controller的程式碼作如下修改。

 

    [ApiVersion("1.0")]
    [Route("api/{v:apiVersion}/values")]
    [ApiController]
    public class ValuesV1Controller : ControllerBase
    {
        [HttpGet]
        public IEnumerable<stringGet()
        
{
            return new string[] { "Value1 from Version 1""value2 from Version 1" };
        }
    }   

    [ApiVersion("2.0")]
    [Route("api/{v:apiVersion}/values")]
    [ApiController]
    public class ValuesV2Controller : ControllerBase
    {
        [HttpGet]
        public IEnumerable<stringGet()
        
{
            return new string[] { "value1 from Version 2""value2 from Version 2" };
        }
    }

現在我們透過以下2個Url請求Api, 傳回的結果如下 :


/api/2.0/values

 

["value1 from Version 2","value2 from Version 2"]

 

api/1.0/values

 

["Value1 from Version 1","value2 from Version 1"]

如何在請求頭(HTTP Header)中使用版本控制

 

以上的2種方式需要修改請求的Url, 如果你不喜歡這2種方式,Microsoft.AspNetCore.Mvc.Versioning還提供了第三種指定Api版本號的方式,即在HTTP請求頭中新增版本號引數。

 

為了啟用這種方式,我們首先需要在Startup.cs中修改

Microsoft.AspNetCore.Mvc.Versioning的配置, 程式碼如下:

    services.AddApiVersioning(o =>
    {
        o.ReportApiVersions = true;
        o.AssumeDefaultVersionWhenUnspecified = true;
        o.DefaultApiVersion = new ApiVersion(10);
        o.ApiVersionReader = new HeaderApiVersionReader("x-api-version");
    });

 

這裡透過ApiVersionReader屬性指定了Api版本號是從請求頭部的x-api-version屬性來的。

Tips: 一旦你使用o.ApiVersionReader = new HeaderApiVersionReader(“x-api-version”);, 在查詢字串中指定版本號的方式將不再可用,如果你希望同時支援2種方式,請改用o.ApiVersionReader = ApiVersionReader.Combine(new QueryStringApiVersionReader(), new HeaderApiVersionReader() { HeaderNames = { “x-api-version” }});(多謝seamaswang的更正)

下麵我們透過Postman來請求2.0的Api, 結果正確傳回了。

 

其他特性

棄用Api(Deprecated)特性

 

有些時候,我們需要標記一些過時的Api為棄用狀態,但是我們又不希望完全移除這個版本的Api, 我們可以使用Deprecated特性。

 

例:我們當前希望棄用ValuesV1Controller, 我們可以指定Deprecated特性的值為true

 

    [ApiVersion("1.0", Deprecated = true)]
    [Route("api/values")]
    [ApiController]
    public class ValuesV1Controller : ControllerBase
    {
        [HttpGet]
        public IEnumerable<stringGet()
        
{
            return new string[] { "Value1 from Version 1""value2 from Version 1" };
        }
    }

當我們請求在此請求這個api的時候, 在響應頭中會出現api-deprecated-versions和api-supported-versions2個屬性。

 

Response Header
api-deprecated-versions: 1.0
api-supported-versions: 2.0
content-type: application/json; charset=utf-8
date: Sat, 06 Oct 2018 06:32:18 GMT
server: Kestrel
status: 200
x-powered-by: ASP.NET

這段響應的意思就是1.0版本的Api已經過期了,2.0版本中有相同的Api, 可以換用2.0版本的Api。

 

使用ApiVersionNeutral指定不需要版本控制的Api

 

在編寫Api的時候,對於一些非常簡單的Api, 我們可能不需要指定Api版本號, 例如健康檢查Api。我們可以使用ApiVersionNeutral特性,將它從Api版本控制中排除掉。

 

例:

 

    [ApiVersionNeutral]
    [Route("api/[controller]")]
    [ApiController]
    public class HealthCheckController : ControllerBase
    {
        public string Get()
        
{
            return "Good";
        }
    }
已同步到看一看
贊(0)

分享創造快樂