【JavaWeb】一分钟让你学会如何更优雅管理API版本

一.前言

一个web项目中,随着需求的变更或增加,API接口也会跟着变化,而如果APP发布后,已使用的接口肯定不能直接覆盖更新,需要新增升级版本接口和新的APP版本对应,因此多个版本接口更替后,如何更优雅管理不同版本接口代码,如何设计更直观的接口文档呈现给app端,这是我们后端工程师需要考虑的事情,下面总结接口版本管理经验。

二.API版本规范

考虑到接口今后一定会进行版本迭代,因此一开始开发的时候,就需要对代码进行版本考量下的代码目标架构。

1. 控制器目录架构:

v1版本控制器目录:apps/controller/v1/……
v2版本控制器目录:apps/controller/v2/……
    在controller下增加子集文件夹:controller/v1/……、controller/v2/……等等,初始版本的接口全部放在v1下。

2. 接口设计

2.0.利用域名

  • 不同版本使用不同域名,v1.api.amap.com,v2.api.amap.com

2.1.利用URL path

  • 请求URL path区分管理 同一域名,api.amap.com/v1/,api.amap.com/v2/
  • 不同版本控制器代码分类依据
    1. 在项目发布前的所有代码,都属于v1版本代码;

    2. 项目发布后,如果是新增加的需求,和已发布v1版本接口需求不冲突,新增控制器或接口,仍然属于v1版本代码

    3. 项目发布后,如果新增需求和v1已发布版本接口冲突,为了兼容老版本APP,必须在v2文件夹下新增控制器开发v2版本接口。

遵循以上分类原则,依次递推,严格区分不同版本接口代码,结合下一部分的接口文档,利于不同版本接口更新维护。

2.3. 利用自定义的request header

HTTP GET:
http://haveibeenpwned.com/api/breachedaccount/foo
api-version: 2

2.4.利用content type

http://haveibeenpwned.com/api/breachedaccount/foo
Accept: application/vnd.haveibeenpwned+json; version=2.0

2.5.利用URL里的parameter

  • 根据请求参数区分管理 同一域名,请求参数中带version=v1/v2/v3等,然后识别具体版本执行对应方法
HTTP GET:
http://haveibeenpwned.com/api/breachedaccount/foo?version=v2

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

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

1. 小版本升级

小版本的更新,在原接口中做扩展,做兼容

  • 例如:一个应用场景,在1.0.1版本是获取的是总资产和保证金率的数据,在1.0.2版本获取的是总资产和安全边界的数据,在后续的版本获取的是保证金率和安全边界的数据
@RequestMapping(value = "/general", method = RequestMethod.GET)
@ResponseBody
public Result getUserGeneralInfo() {
    
    
	//获取请求头版本号
    String version = RequestHeaderContext.getInstance().getApiVersion();
    if (version.equals("1.0.1")){
    
    
        // 获取总资产和保证金率数据
    } else if (version.equals("1.0.2")){
    
    
        // 获取总资产和安全边界数据
    } else {
    
    
        // 获取保证金率和安全边界数据
    }
   
    return 返回Result ;
}

2. 大版本升级

无法兼容的接口,采用新建Controller,甚至部署新的应用服务和nginx

  • 例如:这次这个接口需要获取的数据是一个List的数据,而不是两个单独的值。
    • 把修改的接口放在新的Controller中,旧的接口不需要处理,客户端自己区分。
@Slf4j
@Controller
@RequestMapping("v1.2/account/user")
public class AccountControllerV2 extends BaseController {
    
    

    @Autowired
    private AccountManager accountManager;

    /**
     * 总资产和保证金率的List数据
     */
    @RequestMapping(value = "/general", method = RequestMethod.GET)
    @ResponseBody
    public Result getUserGeneralInfo() {
    
    
        String version= RequestHeaderContext.getInstance().getApiVersion();
        //获取请求头版本号
        if (version.equals("1.2.1")){
    
    
            // 获取总资产和保证金率数据
        } else if (version.equals("1.2.2")){
    
    
            // 获取总资产和安全边界数据
        } else {
    
    
            // 获取保证金率和安全边界数据
        }
        return Result返回List数据;
    }
}

四.总结

1. 接口变动非常大或者整个产品大版本发布

  • 此种情况下可以采用URL自带版本的方式,创建新的Controller,甚至部署新的应用服务和nginx。URL中无版本号即走默认逻辑。

2. 常规的版本升级和BUGFIX

  • 一般情况下使用HTTP Header中指定的版本号,在代码逻辑中进行判断就可满足需求**。Header中无版本号**即走默认处理逻辑`。

3. 两种模式同时使用

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

猜你喜欢

转载自blog.csdn.net/qq877728715/article/details/107001890
今日推荐