APP接口升级设计策略

作者: 小怪聊职场 | 来源:发表于2018-11-05 18:04 被阅读19次

    API版本管理规范

    良好的API需要保持向前兼容,特别是在APP场景或者是其他第三方客户端的场景,产品需求的升级改进要求不影响现有的版本正常工作。因此对外暴露的所有API需要有统一的版本管理策略来应对兼容性问题。

    版本控制模式

    根据不同的应用场景,制定了两种API的版本控制模式:
    1. API(URL)自带版本

    https://www.fota.com/api/account/user/general?_t=1541397626404
    https://www.fota.com/api/v1.2/account/user/general?_t=1541397626404
    https://www.fota.com/api/v1.3/account/user/general?_t=1541397626404
    

    2. HTTP Header指定版本

    :authority: fota.com
    :method: GET
    :path: /api/account/user/general?_t=1541402217410
    :scheme: https
    accept: application/json, text/plain
    accept-encoding: gzip, deflate, br
    api-version:1.0.1
    

    API版本升级方案约定和案例

    开闭原则。
    对于小版本的更新可以在单个接口中进行处理,对于大版本的更新,可以提供新的Controller,或新建服务部署新版本的接口,保留每个版本的服务。

    1. 小版本升级
    小版本的更新,在原接口中做扩展,做兼容。例如:一个应用场景,在1.0.1版本是获取的是总资产和保证金率的数据,在1.0.2版本获取的是总资产和安全边界的数据,在后续的版本获取的是保证金率和安全边界的数据。

    @Authorization
    @RequestMapping(value = "/general", method = RequestMethod.GET)
    @ResponseBody
    public Result getUserGeneralInfo() {
        String apiVersion = RequestHeaderContext.getInstance().getApiVersion();
        if (apiVersion.equals("1.0.1")){
            // 获取总资产和保证金率数据
        } else if (apiVersion.equals("1.0.2")){
            // 获取总资产和安全边界数据
        } else {
            // 获取保证金率和安全边界数据
        }
        Long userId = tokenUtil.getUserIdByLoginToken(RequestHeaderContext.getInstance().getToken());
        return accountManager.getUserGeneralInfo(userId);
    }
    

    当然,服务端也可以做兼容,把总资产、保证金率和安全边界的数据都返回,保障返回的JSON对象字段只增不删不改,客户端根据自己当前的版本显示不同的值。
    apiVersion的值是从Header获取:

    :authority: fota.com
    :method: GET
    :path: /api/contract/list?contractId=1027&_t=1541402217410
    :scheme: https
    accept: application/json, text/plain
    accept-encoding: gzip, deflate, br
    api-version:1.0.1
    

    2. 大版本升级
    无法兼容的接口,采用新建Controller,甚至部署新的应用服务和nginx。例如:这次这个接口需要获取的数据是一个List的数据,而不是两个单独的值。

    把修改的接口放在新的Controller中,旧的接口不需要处理,客户端自己区分。

    @Slf4j
    @Controller
    @RequestMapping("v1.2/account/user")
    public class AccountControllerV2 extends BaseController {
    
        @Autowired
        private AccountManager accountManager;
    
        /**
         * 总资产和保证金率的List数据
         *
         * @return
         */
        @Authorization
        @RequestMapping(value = "/general", method = RequestMethod.GET)
        @ResponseBody
        public Result getUserGeneralInfo() {
            String apiVersion = RequestHeaderContext.getInstance().getApiVersion();
            if (apiVersion.equals("1.2.1")){
                // 获取总资产和保证金率数据
            } else if (apiVersion.equals("1.2.2")){
                // 获取总资产和安全边界数据
            } else {
                // 获取保证金率和安全边界数据
            }
            Long userId = tokenUtil.getUserIdByLoginToken(RequestHeaderContext.getInstance().getToken());
            return accountManager.getUserGeneralInfo(userId);
        }
    }
    

    在服务端新建Controller,甚至部署新的应用服务和nginx(方便回滚)。

    https://www.fota.com/api/account/user/general?_t=1541397626404
    https://www.fota.com/api/v1.2/account/user/general?_t=1541397626404
    https://www.fota.com/api/v1.3/account/user/general?_t=1541397626404
    

    使用场景

    1. 接口变动非常大或者整个产品大版本发布
    此种情况下可以采用URL自带版本的方式,提供新的Controller,甚至部署新的应用服务和nginx。URL中无版本号即走默认逻辑。

    2. 常规的版本升级和BUGFIX
    一般情况下使用HTTP Header中指定的版本号,在代码逻辑中进行判断就可满足需求。Header中无版本号即走默认处理逻辑。

    3. 两种模式同时使用
    URL自带模式用来处理大版本变动,当大版本已经升级完成,后续的小需求迭代仍然可以使用HEADER的方式来保持API兼容。

    相关文章

      网友评论

        本文标题:APP接口升级设计策略

        本文链接:https://www.haomeiwen.com/subject/ynzsxqtx.html