Thrift 文件 (api) 版本控制的最佳实践是什么? [英] What's the best practice to for Thrift file (api) versioning?

查看:25
本文介绍了Thrift 文件 (api) 版本控制的最佳实践是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用 thrift 编写的 API.示例:

I have an API written in thrift. Example:

service Api {
  void invoke()
}

它做了一些事情.我想更改行为以执行其他操作,但仍为期望旧行为的客户保留旧行为.

It does something. I want to change the behavior to do something else but still keep the old behavior for clients that expect the old behavior.

处理新 API 版本的最佳做法是什么?

What's the best practice to handle a new API version?

推荐答案

Soft versioning

Thrift 支持软版本控制,因此执行如下所示的服务版本 2 是完全有效的:

Soft versioning

Thrift supports soft versioning, so it is perfectly valid to do a version 2 of your service which looks like this:

service Api {
   void invoke(1: string optional_arg1, 2: i32 optional_arg2) throws (1: MyError e)
   i32 number_of_invokes()
}

由于新添加的参数在技术上是可选的,任意客户端请求可能包含也可能不包含它们,或者可能只包含它们的一部分(例如指定 arg1 但不指定 arg2).异常有点不同,旧客户端会引发某种通用的意外异常或类似的异常.

Since the newly added arguments are technically optional, an arbitrary clients request may or may not contain them, or may contain only parts of them (e.g. specify arg1 but not arg2). The exception is a bit different, old clients will raise some kind of generic unexpected exception or similar.

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

It is even possible to remove an outdated function entirely, in this case old clients will get an exception whenever they try to call the (now non-existing) removed function.

在向结构、异常等中添加成员字段方面,上述所有内容都同样适用.建议不要从 IDL 文件中删除声明,而是注释旧的已删除成员字段和函数以防止人们在更高版本中重复使用旧字段 ID、旧函数名称或旧枚举值.

All of the above is similarly is true with regard to adding member fields to structures, exceptions etc. Instead of removing declarations from the IDL file, it is recommended to comment out old removed member fields and functions to prevent people from re-using old field IDs, old function names or old enum values in later versions.

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,您将需要携带这个 API,直到整个结构被删除.稍后添加新的 required 字段也是如此.否则你会冒着破坏更改的风险,因为混合新旧客户端和服务器迟早会产生这样一种情况:一端绝对期望某个 required 成员字段,但另一端无法交付,仅仅是因为它对此一无所知.

required is forever

Where you need to be careful is the use of the keyword required. Once you publish an API with a struct containing an required member, you will need to carry this one until the structure as a whole is removed. Same is true with adding new required fields later on. Otherwise you risk breaking changes, because mixing old and new clients and servers will sooner or later produce a situation where one end absolutely expects a certain required member field, but the opposite end can't deliver, simply because it does not know anything about it.

这对于普通或 optional 字段来说不是问题,因为 Thrift 被设计为跳过未知字段(类型 ID 包含在连线数据中),而只是忽略缺失的字段.相比之下,对必填字段应用了额外的检查,以确保它们存在于电线数据中.

This is not a problem with normal or optional fields, since Thrift is designed to skip over unknown fields (the type ID is contained in the wire data), and just ignore missing fields. In contrast, additional checks are applied for required fields to ensure they are present in the wire data.

虽然软版本控制是一个很好的工具,但由于需要兼容,它以累积负担为代价.此外,在某些情况下,您的 API 会进行重大更改,故意不向后兼容.在这种情况下,建议在不同的端点设置新服务.

Although soft versioning is a great tool, it comes at the cost of cumulating burdens due to the need to be compatible. Furthermore, in some cases your API will undergo breaking changes, intentionally without being backwards compatible. In that case, it is recommened to set the new service at a different endpoint.

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

Alternatively, the multiplex protocol introduced with Thrift 0.9.2 can be used to offer multiple services and/or service versions over the same endpoint (i.e. socket, http URI, ...)

这篇关于Thrift 文件 (api) 版本控制的最佳实践是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆