• 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。

  • 相关阅读:
    Yii2安装任务调度扩展
    分享书籍[writing idiomatic python ebook]
    python待解决问题笔记
    dojo使用笔记: 自定义ConfirmDialog
    dojo使用疑难杂症集锦
    学习"大众点评网的架构设计与实践"
    一个前端html模板处理引擎(javascript)
    日历设计之重复事件规则设计
    TCP/IP之TCP的建立与终止
    python正则表达式
  • 原文地址:https://www.cnblogs.com/lanhaipeng/p/16209430.html
Copyright © 2020-2023  润新知