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。

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