zoukankan      html  css  js  c++  java
  • webapi 版本控制

    一、问题

       软件开发过程中,常常会需要变更以前的接口,添加或删除接口请求字段,接口字段校验、甚至是变更请求/返回字段名称,如果强制要求所有客户端跟着一起升级代价太大。如果接口从一开始就考虑到了版本的设计,那么做到平滑升级就很容易了。

    二、版本控制方式

    1、利用url传入版本

    以@RequestMapping("/api")controller为例:

    在路径里传入版本号:

    优点:可以做到大版本切换,路由下的所有接口同时更新

    缺点:实际中往往不会涉及很多接口同时升级,并且往往难以控制不同接口的版本(版本管理容易混乱)

        /**
         * http://localhost:8090/api/v1/getUser/111
         * {"userId":111,"userName":"小明"}
         *
         * @param userId
         * @return
         */
        @RequestMapping(value = "/v1/getUser/{userId}")
        public GetUserV1Response getUserInfoV1(@PathVariable("userId") Integer userId) {
            return new GetUserV1Response(userId, "小明");
        }

    通过参数传入(POST 或 GET)

    可以单独控制,注意version不存在和乱传值的处理

        /**
         * http://localhost:8090/api/getUser/111?version=v1
         * {"userId":111,"userName":"小明"}
         * <p>
         * http://localhost:8090/api/getUser/111?version=v2
         * {"userId":111,"userName":"小明","notes":"version 2"}
         *
         * @param userId
         * @return
         */
        @RequestMapping(value = "/getUser/{userId}")
        public Object getUserInfo(@PathVariable("userId") Integer userId, @RequestParam("version") String version) {
            if ("v1".equals(version)) {
                return new GetUserV1Response(userId, "小明");
            }
            return new GetUserV2Response(userId, "小明", "version 2");
        }

    2、利用request header

    以@RequestMapping("/api2")controller为例:

    header设置在Controller或Action上都可以,设置在Controller上,控制所有Action的版本,设置在Action上,单独控制一个Action的版本

    @RestController
    @RequestMapping(value = "/api2")
    public class ApiVersionHeaderDemoController {
        @Autowired
        private HttpServletRequest request;
    
        //request header
        @RequestMapping(value = "/getUserById/{userId}", headers = "version=v2")
        public Object getUserInfo(@PathVariable("userId") Integer userId) {return new GetUserV2Response(userId, "小明", "version 2");
        }
    }

     对应版本:

    不支持的版本:

    3、利用content type

    利用自定义请求的Content-Type来控制版本:

        /**
         * 请求的是 application/vnd.apiversioncontrol.v1+json
         * 返回的是 application/json;charset=UTF-8
         * v1 是api版本
         *
         * @param userId
         * @return
         */
        @RequestMapping(value = "/getUserById/{userId}", consumes = "application/vnd.apiversioncontrol.v1+json")
        public Object getUserInfoV11(@PathVariable("userId") Integer userId) {
            return new GetUserV2Response(userId, "小明", "version 2");
        }

    返回的是Content-Type:application/json;charset=UTF-8(不指定produces,默认是application/json;charset=UTF-8)

     同时指定request和response的Content-Type为:application/vnd.apiversioncontrol.v2+json 

        /**
         * 请求、返回Content-Type都是 application/vnd.apiversioncontrol.v1+json
         * v1 :为api版本
         *
         * @param userId
         * @return
         */
        @RequestMapping(value = "/getUserById/{userId}", consumes = "application/vnd.apiversioncontrol.v2+json", produces = "application/vnd.apiversioncontrol.v2+json")
        public Object getUserInfoV12(@PathVariable("userId") Integer userId) {
            return new GetUserV2Response(userId, "小明", "version 2");
        }

    同时指定request和response的Content-Type为:application/vnd.apiversioncontrol+json;version=v2

        /**
         * 请求、返回Content-Type都是 application/vnd.apiversioncontrol+json;version=v2
         * v2 :为api版本
         *
         * @param userId
         * @return
         */
        @RequestMapping(value = "/getUserById/{userId}", consumes = "application/vnd.apiversioncontrol+json;version=v2", produces = "application/vnd.apiversioncontrol+json;version=v2")
        public Object getUserInfoV2(@PathVariable("userId") Integer userId) {
            return new GetUserV2Response(userId, "小明", "version 2");
        }

     三、注解实现

    注解来实现:SpingMVC框架实现restfull接口的版本控制

    参考:webapi-version-control

  • 相关阅读:
    yolo2 anchor选择校招总结
    rfcn校招总结
    cascade rcnn
    sort论文和代码解读
    重要的观点
    代办项
    stixel上边缘
    resnet densenet
    最小二乘法和线性回归
    逻辑回归原理
  • 原文地址:https://www.cnblogs.com/mr-yang-localhost/p/8973160.html
Copyright © 2011-2022 走看看