zoukankan      html  css  js  c++  java
  • Asp.Net.Core WebApi 版本控制

    前言

    在后端Api的开发过程中,无法避免的会遇到接口迭代的过程,如何保证新老接口的共存和接口的向前的兼容呢,这时候就需要对Api进行版本的控制,那如何优雅的控制Api的版本呢?

    开始

    Microsoft.AspNetCore.Mvc.Versioning 是一个微软官方推出的一个用于管理Api版本的包,配置简单,功能强大。 github地址.

    新建一个WebApi项目并通过命令引用包。

    Install-Package Microsoft.AspNetCore.Mvc.Versioning

    最新版本已经支持Core3.1

    20200409110106

    项目结构如下

    20200409112646

    StartupConfigureServices 中增加一下配置。

    services.AddApiVersioning(options =>
    {
        options.ReportApiVersions = true; 
        options.AssumeDefaultVersionWhenUnspecified = true; 
        options.DefaultApiVersion = new ApiVersion(1, 0); 
    });
    
    • ReportApiVersions:是否在请求头中返回受支持的版本信息。
    • AssumeDefaultVersionWhenUnspecified:请求没有指明版本的情况下是否使用默认的版本。
    • DefaultApiVersion:默认的版本号。

    通过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() 是用于获取请求接口的版本信息。

    我们通过postman来请求这两个接口当我们没有给到具体请求哪个版本的时候会根据在ConfigureServices中配置的默认版本去执行。

    20200409152911

    指定版本请求结果

    20200409153048

    20200409153124

    在响应头中会显示当前支持的所有的Api版本

    20200409153317

    通过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());
        }
    }
    

    通过postman进行测试

    20200409154746
    20200409155617
    20200409155705

    可以看到当我们使用指定的版本是可以正常访问的时候,但是如果我们去掉了Api版本号就会抛出404,并不能像QueryString一样调用默认的Api版本,因为URL Path的方式不允许隐式匹配设置的默认Api版本。所以必须申明所有的Api版本。且在请求Api同时必须带上Api版本号。

    通过Media Type进行版本控制

    我们还可以使用content-type来实现版本的控制

    修改ConfigureServices中的配置

    services.AddApiVersioning(options =>
    {
        options.ApiVersionReader = new MediaTypeApiVersionReader();
        options.AssumeDefaultVersionWhenUnspecified = true;
        options.ApiVersionSelector = new CurrentImplementationApiVersionSelector(options);
    
    });
    

    CurrentImplementationApiVersionSelector 如果没有在content-type中传递Api版本好,将默认匹配最新的Api版本

    分别修改两个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());
        }
    }
    

    使用Postman测试

    QQ20200409-163007

    通过自定义Headers进行版本控制

    修改ConfigureServices中的配置

    services.AddControllers();
    services.AddApiVersioning(options =>
    {
        options.ReportApiVersions = true;
        options.ApiVersionReader = new HeaderApiVersionReader("api_version");
        options.AssumeDefaultVersionWhenUnspecified = true;
        options.DefaultApiVersion = new ApiVersion(1, 0);
    });
    

    api_version 是你Headers中Key的名字。

    使用Postman测试
    QQ20200409-163921

    特性

    当哪个Api版本不在更新,就需要弃用掉这个版本。当Deprecated值为true时说明该Api版本已经已经弃用,但是弃用不代表不能请求。只是会在响应头中告知次版本已经已经弃用。

    namespace version.Controllers.v1
    {
        [ApiVersion("1.0",Deprecated= true)]
        [ApiController]
        [Route("api/[controller]")]
        public class ValuesController : Controller
        {
            [HttpGet("version")]
            public string Version() => (HttpContext.GetRequestedApiVersion().ToString());
        }
    }
    

    20200409164902

    项目总有一些功能是不需要版本的控制,所以我们希望它不受版本控制。可以添加[ApiVersionNeutral]特性使Api支持版本控制。

    namespace version.Controllers.v1
    {
        [ApiVersionNeutral]
        [ApiController]
        [Route("api/[controller]")]
        public class ValuesController : Controller
        {
            [HttpGet("version")]
            public string Version() => (HttpContext.GetRequestedApiVersion().ToString());
        }
    }
    

    MapToApiVersion 可以将单个Api归类于任何版本。在一个Controller中可以存在多个版本的Api。我们可以配合Deprecated来灵活的控制我们的Api。

    namespace version.Controllers.v1
    {
        [ApiVersion("3.0")]
        [ApiVersion("1.0",Deprecated= true)]
        [ApiController]
        [Route("api/v{version:ApiVersion}/[controller]")]
        public class ValuesController : Controller
        {
            [HttpGet("version"), MapToApiVersion("1.0")]
            public string Version() => (HttpContext.GetRequestedApiVersion().ToString());
    
            [HttpGet("version3"), MapToApiVersion("3.0")]
            public string Version3() => (HttpContext.GetRequestedApiVersion().ToString());
        }
    }
    

    通过postman测试一下。

    QQ20200409-173445

    总结

    可以看到Microsoft.AspNetCore.Mvc.Versioning功能还能强大的,基本满足了大部分的需求,还有一些功能可能没有在本文中涉及到,可以去这里.翻阅。

  • 相关阅读:
    2013-06-28,“万能数据库查询分析器”在中关村本月数据库类下载排行中重返前10位
    Oracle 存储过程
    强化学习精要:核心算法与TensorFlow实现
    深入理解TensorFlow:架构设计与实现原理
    Vue.js实战
    TensorFlow机器学习实战指南
    深入浅出React和Redux
    Flutter技术入门与实战
    TensorFlow:实战Google深度学习框架
    深度学习:一起玩转TensorLayer
  • 原文地址:https://www.cnblogs.com/linhuiy/p/12668535.html
Copyright © 2011-2022 走看看