Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Versioning 什么';保存旧文件(api)版本控制的最佳实践是什么?_Versioning_Thrift - Fatal编程技术网

Versioning 什么';保存旧文件(api)版本控制的最佳实践是什么?

Versioning 什么';保存旧文件(api)版本控制的最佳实践是什么?,versioning,thrift,Versioning,Thrift,我有一个用thrift编写的API。例如: service Api { void invoke() } 它有作用。我想改变行为来做其他事情,但仍然为期望旧行为的客户保留旧行为 处理新API版本的最佳实践是什么?软版本控制 Thrift支持软版本控制,因此完全可以对您的服务进行如下版本2: service Api { void invoke(1: string optional_arg1, 2: i32 optional_arg2) throws (1: MyError e) i

我有一个用thrift编写的API。例如:

service Api {
  void invoke()
}
它有作用。我想改变行为来做其他事情,但仍然为期望旧行为的客户保留旧行为

处理新API版本的最佳实践是什么?

软版本控制 Thrift支持软版本控制,因此完全可以对您的服务进行如下版本2:

service Api {
   void invoke(1: string optional_arg1, 2: i32 optional_arg2) throws (1: MyError e)
   i32 number_of_invokes()
}
由于新添加的参数在技术上是可选的,因此任意客户端请求可能包含或不包含这些参数,或者可能只包含部分参数(例如,指定
arg1
,但不指定
arg2
)。异常有点不同,旧客户机将引发某种一般的意外异常或类似异常

甚至可以完全删除过时的函数,在这种情况下,旧客户机在尝试调用(现在不存在)已删除的函数时会出现异常

在向结构、异常等添加成员字段方面,上述所有情况都是类似的。建议注释掉旧的已删除成员字段和函数,以防止人们重新使用旧的字段ID,而不是从IDL文件中删除声明,较新版本中的旧函数名或旧枚举值

struct foobar {
  // API 1.0 fields
  1: i32 foo
  //2: i32 bar   - obsolete with API 2.0

  // API 2.0 fields
  3: i32 baz
}
必需的
是永久的 您需要注意的是关键字
required
的使用。一旦发布了包含
required
成员的结构的API,您将需要携带该结构,直到整个结构被删除。以后添加新的
必填
字段也是如此。否则,您就有破坏更改的风险,因为新旧客户机和服务器的混合迟早会产生这样一种情况:一端绝对期望某个
必需的
成员字段,而另一端却无法交付,因为它对该字段一无所知

这对于普通或
可选
字段不是问题,因为Thrift设计用于跳过未知字段(类型ID包含在wire数据中),而忽略缺少的字段。相反,对
必需的
字段进行额外检查,以确保它们存在于导线数据中

端点 尽管软版本控制是一个很好的工具,但由于需要兼容,它以累积负担为代价。此外,在某些情况下,您的API将经历突破性的更改,故意不向后兼容。在这种情况下,建议在不同的端点设置新服务


或者,Thrift 0.9.2引入的可用于在同一端点(即套接字、http URI等)上提供多个服务和/或服务版本。

对于您的特定场景,您只需添加一个新方法(命名为其他方法)即可完成新任务。在将来,我将避免命名方法
invoke
或类似的方法。您的服务现在将有一个方法
invoke
,该方法执行一些未知的操作,另一个方法(希望命名更好)执行它所说的操作。这可能会导致您的用户感到困惑,但一切仍然有效