移动app为什么要做版本控制
应用升级无法做到全部升级。比如某应用现行1.1版本,某次开发升级后,版本变为1.2。除app界面变化外,后台接口也发生了变化。然而不是所有的用户都在第一时间升级了app,或者由于版本推送不及时,用户忽略更新等原因,1.1和1.2的app将会在很长一段时间内同时运行。如果不做版本控制,导致1.1版本的用户无法正常使用app,从用户角度讲,是一个很不友好的体验。很常见的一个场景,比如推送更新的时候,我正在户外,没有wifi,我想等回家了再更新,然而我现在就需要使用这个app。
判断是否需要做版本控制
如何判断一个接口改造是否需要版本控制,分为以下几个场景:
- 如果是改变接口的业务逻辑,而接口的入参和出参都保持不变,这样的迭代对于app是无感知的。这样的迭代可以不需要版本控制,直接迭代后端代码即可。
- 如果迭代后的接口的入参或者出参,虽然比之前新增或者减少了参数,但是可以通过给默认值或者兼容空值等方式,兼容老逻辑,那么也可以不做版本控制。通过代码兼容版本,做到不通版本的接口都可以正常使用。
- 如果迭代后的接口入参或者出参变化,不能通过给定默认值的方式兼容。或者说,参数的类型整个都发生了变化,无法复用以前的接口的时候,版本控制就是必要的了。
版本控制的几个方案
部署灰度环境,使用ngix做分发
这种方式,需要服务器机器支持灰度部署。比如,现在服务器有两套,一套灰度,一套新版本。这样在写后端代码的时候,完全不用考虑版本控制的事情,只要在请求里面带上当前app的版本号,然后在nigx里面配置路由规则。将旧版本的请求路由到灰度环境,新版本的请求路由到正式环境。这样的好处是,通过监控灰度流量就可以知道还有多少活动用户没有升级app。如果灰度的请求次数降到一定程度,或者说直接降到0了,就可以把灰度的机器也更新成最新的代码。这种是不论前端还是后端都无感知的代码版本迭代。缺点就是,需要硬件服务器上的支持,不是所有的公司都有灰度环境,就算有,如果版本迭代太快,也无法很好的满足版本控制的需求。
在URL中使用版本编号,通过拦截器分发
在请求url中加入版本信息。例如同样的注册请求(register),如果是1.0.0的版本,则可以将URL设置为 https://test.test.cn/mytest/v1/register。如果是2.0.0的版本,则可以设置为https://test.test.cn/mytest/v2/register。
在controller层中分别注册相应的路径来处理两个接口。
@RequestMapping("/v1")
public class RegisterController {
@RequestMapping(value = "/register", method = RequestMethod.POST)
@ResponseBody
public ResponseVo<LoginInfoVo> register(RegisterParamVo paramVo, HttpServletRequest request) {
// todo register
}
@RequestMapping("/v2")
public class RegisterController {
@RequestMapping(value = "/register", method = RequestMethod.POST)
@ResponseBody
public ResponseVo<LoginInfoVo> register(NewRegisterParamVo paramVo, HttpServletRequest request) {
// todo register
}
在请求参数重使用版本号,通过controller层做分发
这个是属于最不明智的方案,这里只是说明可以这么实现,但是实际开发中不推荐。
在请求参数中新增版本号参数,然后 v1接口的参数和v2接口的出入参全部容于在同一个接口中。然后通过版本号参数,使用简单工厂模式,生产出实际处理的service代码做版本管理。
具体代码:略,此处只提供一个想法。