.Net Core中的Api版本控制

原文連接:API Versioning in .Net Core
做者:Neel Bhattjson

簡介

Api的版本控制是Api開發中常常遇到的問題, 在大部分中大型項目都須要使用到Api的版本控制api

在本篇博客中,咱們將說明一下如何在.Net Core Api項目中使用Api版本控制。app

本篇博客中測試項目的開發環境:ide

  • 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.Versioningcode

修改Startup類

Microsoft.AspNetCore.Mvc.Versioning庫安裝完成以後,下一步咱們來添加Api版本控制服務。server

這裏咱們須要在Startup類的ConfigureService方法中添加如下代碼。blog

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

代碼解釋

ReportApiVersion 屬性是一個布爾類型,若是設置爲true, 在Api請求的響應頭部,會追加當前Api支持的版本, 例ip

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<string> Get()
        {
            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<string> Get()
        {
            return new string[] { "value1 from Version 2", "value2 from Version 2" };
        }
    }

代碼解釋

  • Value1ControllerValue2Controller使用了同樣的路由"/api/values"
  • Value1Controller類頭部使用ApiVersion特性標記了當前Controller的Api版本號是1.0
  • Value2Controller類頭部使用ApiVersion特性標記了當前Controller的Api版本號是2.0
    -Value1ControllerValue2Controller都持有相同方法簽名的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<string> Get()
        {
            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<string> Get()
        {
            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(1, 0);
        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<string> Get()
        {
            return new string[] { "Value1 from Version 1", "value2 from Version 1" };
        }
    }

當咱們請求在此請求這個api的時候, 在響應頭中會出現api-deprecated-versionsapi-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";
        }
    }

本篇源代碼

相關文章
相關標籤/搜索