接口升级兼容老版本的总结

500
APP从1.0升级到2.0,增加了大量特性,并且对老特性也做了较大调整,因此相应地变更了表结构。这时就要求服务端在提供新接口的同时,也需要兼容老版本的客户端。本文总结一下我们的一些做法

数据库调整

首先,增加新表,以及新增字段都是允许的。但是原则是不可以删除老的表和字段,即使新接口已经不再需要,也应该保留。否则很容易想到的结果,就是旧的接口实现无法取到所需的数据,接口协议肯定会有调整。如果老版本的客户端代码比较健壮,有可能能够适应接口的变化,但是一般来说都会有各种问题,比如界面显示不全甚至导致应用crash等。所以老的表和字段是需要保留的

另一方面,对于新增的表和字段,需要考虑对旧表的兼容性。比如新增的字段,一般需要允许为空,这样老的数据才不会出错。或者就要考虑在升级表结构的同时,进行数据迁移

还有一种更复杂的情况,就是新增的字段,对老的接口实现产生了影响,这也是需要考虑的因素。比如旧的表只有一种数据,在2.0时增加了一个type字段,用来保存形式不同的另一种数据。旧的接口实现并没有过滤掉新的数据类型,会返回到客户端,而老版本的客户端是无法识别这种新的数据类型的。所以这时候就需要修改接口的实现,过滤掉新的type类型

总的来说,一个原则就是,无论数据库结构如何变更,只要保证接口协议不变,老版本的客户端一般就不会出现问题

给接口增加分支

接下来就是如何实现新接口的问题。对于改动不大的情况,在实现里增加分支是一种不错的办法

比如新版本的客户端,可以在http header里增加x-version标识,然后接口根据此标识是否存在,进行相应的处理。由于老版本的客户端不携带此标识,还会走到旧的分支里,从而保证了老接口的稳定

新接口单独部署

上述增加分支的做法,只适用于改动不太大的情况。而我们这次的情况,70%以上的接口都发生了变化,再使用分支的方法可能就不是最优的

更合适的做法,是旧接口完全不动。新接口独立部署。比如以下的URL:

1
2
http://api.xxx.com/svc/datas // v1.0 interface
http://api2.xxx.com/svc/datas // v2.0 interface

让新版本的客户端访问另一套接口。这样做的好处是:

  1. 老版本的接口绝对不会受到影响
  2. 当老版本的客户端逐渐升级完成以后,可以简单地停掉老接口的服务
  3. 新版本的代码比较纯净,不用做兼容性判断