zoukankan      html  css  js  c++  java
  • API服务版本控制 Microsoft.AspNetCore.Mvc.Versioning

    我们在进行webapi服务开发时,会遇到一些多个版本的api共存的情况发生,例如某一版本APP上线后,需求发生变更,需要在下一个升级版本更新API,但同时又需要保证这个APP版本能正常使用,这时候就需要采用API服务版本控制。

    版本控制一般有以下几种方式:

    1. 在url上增加查询字符串参数的方式,追加版本,例如 api/service?v=2
    2. 在url路径上增加版本。例如:api/v2/service(这种方式个人认为目前是最优雅的方式)
    3. 在http请求head中加入版本标识

    目前微软提供了 Microsoft.AspNetCore.Mvc.Versioning 组件,能够支持以上几种方式。

    组件注册

                services.AddApiVersioning(options =>
                {
                    options.ReportApiVersions = true;
                    options.AssumeDefaultVersionWhenUnspecified = true;
                    options.DefaultApiVersion = new ApiVersion(1, 0);
                });
    • ReportAPIVersions: 这是可选的。但是, 当设置为 true 时, API 将返回响应标头中支持的版本信息。
    • AssumeDefaultVersionWhenUnspecified: 此选项将用于不提供版本的请求。默认情况下, 假定的 API 版本为1.0。(这个经测试对url追加版本方式不起作用)
    • DefaultApiVersion: 此选项用于指定在请求中未指定版本时要使用的默认 API 版本。这将默认版本为1.0。

    几个重要的类

    • ApiVersion 特性标识当前Controller的版本,注意路由的配置。这里我们采用了第 2 个版本控制方式
    • MapToApiVersion 属性允许将单个 API 操作映射到某一版本

    实现一个小需求:在同一个Controller里面新增一个api版本

      http://localhost:5000/gateway/api/user/headclaims           --->指向 默认v1版本

      http://localhost:5000/gateway/api/v1/user/headclaims      ---->指向 v1版本

      http://localhost:5000/gateway/api/v2/user/headclaims      ---->指向 v2版本

    配置如下:

        [ApiVersion("1.0")]
        [ApiVersion("2.0")]
        //多路由支持
        [Route("api/v{version:apiVersion}/[controller]")]
        [Route("api/[controller]")]
        [ApiController]
        public class UserController : ControllerBase
        {
            private readonly IUserAppService _userService;
            public UserController(IUserAppService userService)
            {
                _userService = userService;
            }
     
            [Route("headclaims")]
            [HttpGet]
            public IActionResult HeadClaims()
            {
                var claimTypes = new List<string> { "name", "phone", "userId", "introduce" };
                var claimHeads = Request.Headers.Where(x => claimTypes.Contains(x.Key));
                var user = Request.HttpContext.User;
                if (claimHeads == null) return Ok();
                var returnObj = new JObject();
                foreach (var ch in claimHeads)
                {
                    returnObj.Add(ch.Key, ch.Value.ToString());
                }
                return Ok(returnObj);
            }
            [Route("headclaims")]
            [HttpGet, MapToApiVersion("2.0")]
            public IActionResult HeadClaimsv2()
            {
                var claimTypes = new List<string> { "name", "phone" };
                var claimHeads = Request.Headers.Where(x => claimTypes.Contains(x.Key));
                var user = Request.HttpContext.User;
                if (claimHeads == null) return Ok();
                var returnObj = new JObject();
                foreach (var ch in claimHeads)
                {
                    returnObj.Add(ch.Key, ch.Value.ToString());
                }
                return Ok(returnObj);
            }
        }
  • 相关阅读:
    char *详细指针
    UIScrollViewA都PI得知。
    Android动画之二:View Animation
    计算机基本知识拾遗(七)页面缓存数据的同步和恢复机制页
    得到Android系统语言设置
    Harry Potter and the Prisoner of Azkaban
    zerglurker的c语言教程006——第一功能
    ExtJs迄今datefield控制设置默认值
    quick 2.23 它们的定义c++代码lua与总结的一些细节
    uva live 6190 Beautiful Spacing (二分法+dp试 基于优化的独特性质)
  • 原文地址:https://www.cnblogs.com/gt1987/p/12486140.html
Copyright © 2011-2022 走看看