|
在开发中,我们进行线上升级后,接口的请求或者响应往往发生改变,而有的客户端版本由于某种原因仍就保留旧版本,我们就要对旧版本进行兼容。解决的思路之一是给接口加版本号。举个例子。通常服务器跟客户端交互的时候用序列化的数据格式如json的交互
在1.0版本,有一个接口:
{
"method": "get_user_info",
"params": {
"id":12345,
"name": "xp"
}
}id和name字段都是必须字段。服务端的代码会对这两个字段进行检查。
jsonParser parser(req);
if(parser.has("id")==false ) {
// error handle
}
if(parser.has("name")==false ) {
// error handle
}
如果不存在就报错返回。接口升级到1.1后,接口增加了字段 age。
{
"method": "get_user_info",
"params": {
"id":12345,
"age":12345,
"name": "xp"
}
}这个时候如果客户端还是旧版本,服务端仍然检测这个这个字段就会出问题。
jsonParser parser(req);
if(parser.has("id")==false ) {
// error handle
}
if(parser.has("name")==false ) {
// error handle
}
if(parser.has("age")==false ) {
// error handle
}
为了解决这种请求或者响应中字段的增减造成的兼容问题,我们可以在请求或者响应中加入version字段,针对不同的version,后台服务端作出不同的处理。
{
"method": "get_user_info",
"params": {
"id":12345,
"age":12345,
"version":1,
"name": "xp"
}
}我们根据这个版本号来决定是否检测age字段。同时客户端对这个接口进行请求时,必须传version字段。
那么旧的客户端传的版本号1,新的客户端传的事版本号2。我们的代码如下:
jsonParser parser(req);
if(parser.has("version")==false ) {
// error handle
}
if(version==1) {
int id=parser.get("id");
string name=parser.get("name");
}
if(version==2) {
int age=parser.get("age");
}
数据结构在不同的地方表现的形式不一样。在网络字节流中,可能是json,protobuf。在c++代码中是struct。在sql中,是表结构。
在rpc接口中,也会遇到这种问题。例如一个接口
struct sFooReq {
int id;
string name;
};
int rpc_foo(sFooReq &erq, sFooRsp &rsp);
服务端增加了字段age并更新了程序,然后客户端仍然是旧版。服务端对旧版的客户端传过来传过来的请求做序列化的时候就会出现问题。
mysql也是如此。原来的表查询只有两个字段,如果增删了字段,select的时候又要兼容以前的接口就会出现问题。
而这些则统统可以通过加版本字段的方式解决。 |
|