【翻译】API版本管理:它是什么,为什么这么难?

API版本管理是个复杂话题,版本划分常被视为对客户的不友好行为。API应支持兼容性变化,如TCP/IP、HTTP和HTML,遵循不拿走任何东西、不改变任何东西的含义、新增功能可选的规则。然而,实际操作中,API往往因功能增加而分叉,导致消费者成本增加。正确的做法是避免破坏性变化,确保向后兼容,必要时采取并排部署以减轻消费者负担。

如果你想在API技术专家之间展开一场辩论,只要让他们分享他们对 "API版本 "的看法。可以肯定的是,你会在短时间内发现一些强烈的感受。术语 "API版本 "已经成为 "改变API "的同义词,这是理清支持已发布的API持续变化而又不给API消费者带来不必要问题的明智策略的第一个障碍。

大多数API不需要版本,它们需要的是支持随着时间的推移进行兼容变化的能力(这个词不那么华丽,对吧?)有很多技术支持兼容变化的例子,比如TCP/IP、HTTP和HTML。大多数编程语言也是这样做的。成功地实施兼容的变化需要做出支持变化的承诺,并长期坚持这一承诺。就这么简单,但并不那么容易。

最有效的兼容变化的API可以继续增加功能而不破坏现有的API消费者--即使是多年前创建的消费者。最不有效的API变化要求所有的API生产者和消费者在每次API设计更新时都要重写和重新发布他们的代码。成功的关键是,从一开始就设计好对兼容变化的支持。有了这个支柱,随着时间的推移,实施和发布兼容版API的过程会变得更加一致、可预测和有弹性。

而这正是我们都需要的,对吗?

版本划分是对客户的 "中指"。

在网络上维护API的关键挑战之一是处理随时间变化的问题。简单地说,一旦你发布了你的API,人们开始使用它,这个接口就代表了一种依赖性。API的消费者依赖于API的稳定性和可靠性。

但是很多时候,服务器端的团队(API生产者)忽略了这种依赖性。相反,他们只是简单地做出改变,而很少考虑到他们传递给API消费者的努力成本。正如Roy Fielding(REST名人)在2013年的一条推文中所说:

"......'v1'是对你的API客户的一个中指......"

从API生产商到API消费者的中指,本质上意味着,"是的,我们改变了我们的API,处理它"。 好消息是,通常的做法是在一个新的URL上开始一个新的版本--从api.example.org/v1/customers移到api.example.org/v2/customers。至少这样可以将变化隔离到一些新的分支。但是,情况变得更糟了;这些割裂性的决定通常会附带一个期限(例如,"我们将在180天内关闭现有的API版本")。

无论哪种方式,API消费者都会被卡在袋子里。我甚至看到过一些公司为了增加新的功能而创建了新版本的API。现在,如果消费者想使用新的功能,他们需要停止目前的工作,将时间和预算投入到新的冲刺中,以解决与他们所使用的API的新版本的冲突。有时,这些API消费者团队并不想要或需要这些新功能。所有的费用都被浪费了。

再加上最近的快速发布,你可以想象API的下游成本会变成什么样。我已经看到了不止一个API项目通过搅动下水道的方式直接花掉了它的生意。

确实是中指。

如果他们能做到这一点,你也可以。

当然,在运行的系统中安全地添加非破坏性的改变并不是什么新鲜事。事实上,它是互联网标准工作的基石。被许多人视为 "个人电脑之父 "的Alan Kay指出,几十年来,构建TCP/IP协议栈的每一行代码都已被替换。然而,在所有这些变化中,TCP/IP仍能正常工作。

另一个很好的例子是,HTTP协议本身也支持随时间变化而不被破坏。在HTTP的UPGRADE命令中,有一个完整的设计工作,包括专门的状态代码(101切换协议和426需要升级),以及一个定义明确的交互列表来处理从一个协议到另一个协议的变化。

最后,为了避免你认为这种级别的变化支持仅限于低级别的协议元素,HTML规范是建立在 "忽略未知标记 "的原则之上的。在HTTP和HTML的早期,事情发展得如此之快,以至于继续推动规范发展的唯一安全方式就是建立这样一条规则:任何浏览器在遇到无法识别的元素或元素属性时,都应该像该标签不存在一样行事。这使得快速更新HTML的功能成为可能,而不会增加HTML客户端应用程序(浏览器)的 "可破坏性"。

(注:参见Bert Bos 2001年关于"W3C、XML和标准化"的演讲,以了解早期HTTP/HTML设计的一些情况。)

而所有这些例子都可以追溯到指导大多数互联网标准本身创建的一个基本规则。Jon Postel在1980年提出的"稳健性原则":

"在你所做的事情上要保守,在你接受别人的东西上要自由"。

因此,我们当然有能力管理长期的变化而不至于崩溃。但为什么它看起来如此难以实施和支持?我认为这来自于一个公司的IT社区内缺乏共同的原则。从本质上讲,我们太懒了,不愿意做这些工作。

但这不一定是这样的。

API的希波克拉底誓言

正确管理API的长期变化的第一条规则是不要把破坏性的变化提交给生产。原因很简单:一旦你发布了你的API,人们开始使用它,这个界面就是一个承诺。而打破这一承诺可能意味着失去客户。正如亚马逊的Werner Vogels所说的那样:"API是永远的"。他在2016年的一篇博文中说、

"[在亚马逊] 我们知道,设计API是一项非常重要的任务,因为我们只有一次机会来做好它。"

这实质上是API设计者和开发者的一种 "希波克拉底誓言":"首先,不要造成伤害"。

依靠API持续发展的公司知道这个承诺有多重要。特别是那些通过API获得收入的公司。当每次有人成功使用你的API时,你就会得到报酬,你就会开始把不破坏性的改变作为优先事项。

向后兼容的3个规则

有一些简单的实施规则,你可以用来减少在你的API生态系统中引入破坏性变化的可能性。如果你想长期成功地管理API,将这些作为你的API设计和审查实践的一部分是非常重要的。

规则一:不要拿走任何东西。

第一条规则是,一旦你发布了一个API,你就不能从它那里拿走东西。你不能拿走一个承诺的URL,一个输入参数,或一个输出数据点。即使你在文档中告诉 开发者你的API的某些元素可能会消失或改变,你仍然不能这样做。因为,嗯,开发人员。

这第一条规则的真相在被称为 "海勒姆法则"或 "隐性依赖法则 "的东西中得到了解释:

"如果有足够数量的API用户,你在合同中承诺什么并不重要: 你的系统的所有可观察到的行为都会被某人所依赖。"
- Hyrum Wright,谷歌的员工软件工程师。

这也适用于枚举值。如果你有一个名为status的字段,并记录了它有五个可能的值,你就不能在以后发布API的更新时,status只有四个可能的值。

规则二:不要改变任何东西的含义。

第二条规则指出,你不能改变你的API中现有元素的含义。如果你承诺过滤器语句中的count参数是指 "用户数",那么你以后就不能把同一个参数改为 "页面数"。

改变事物的含义与拿走它并以其他东西取代它的效果相同。那是一种破坏性的改变,也是你对API的希波克拉底誓言的放弃。

规则三:所有的新增功能都是可选的。

第三条规则是,任何新的功能(URL、输入参数和输出参数)都必须被视为可选。如果你的addCustomer操作在最初的版本中采取了四个必要的参数,你就不能增加一个新的、第五个必要的参数。同样,这实质上是拿走了旧的addCustomer方法,而用一个非向后兼容的addCustomer版本来代替它。

好吧,但是如果你被要求做一个突破性的改变呢?

用叉子叉住它,你就完了!

当然,在有些情况下,你别无选择,只能引入一个突破性的变化。也许你的团队搞砸了,API泄露了个人身份信息,或者一些法规发生了变化,你不再被允许接受或分享数据,等等。当这种情况发生时,是时候拿出你的分叉了。因为一个API的新 "版本 "实际上只是一个致命的分叉(用软件术语说)。

分叉是软件工程中一个相当著名的术语。它可以追溯到20世纪80年代初通过Usenet的在线讨论,指的是在一个项目的主干上创建一个分支。当时的假设是,一旦你从你的分叉处分支,你就不会再期望合并到主干上了。虽然我们今天在软件工程中经常使用主干、分支和合并,但API往往会随着时间的推移而 "保持分叉",很少再合并到一起。

如果你知道你需要引入一个突破性的变化,分叉你的API并在一个新的URL空间中发布它。如果你愿意,可以称之为 "版本"。但你仍然不是詹姆斯-邦德,所以要注意,发布新版本并不意味着你可以杀死旧版本。相反,你需要将它们并排运行一段时间。这就避免了我们前面提到的整个 "中指 "的情况。

有了并排的API,API消费者可以继续使用他们当前的API版本,直到他们准备好在未来的某个时间点进行升级--这是他们自己的时间表,而不是你的。

Salesforce是一家非常了解如何分叉API以获得乐趣和利润的公司。他们有一个习惯,每年发布三次新版API。他们2021年春季的API是51版。我最后一次检查显示,他们支持所有以前的版本,可以追溯到2014年春季(也就是v30!)。是的,Salesforce支持20个过去的版本,并排在一起。

开源冠军Eric S. Raymond将 "分叉 "与悲惨或代价高昂的事件联系起来。创建软件分叉通常表明存在无法解决的分裂,并意味着大量的重复工作。而且,正如我们在Salesforce模式中看到的那样,在API领域也是如此。

如果你致力于发布突破性的变化,你也需要致力于并排发布、文档、在线支持,等等。

离别时的一些镜头

所以,整个版本控制的故事其实都是关于随时间变化的。当涉及到API时,我们不能停止时间,也不能避免变化。相反,我们需要想出一个稳定的、具有成本效益的方法来处理它们。

API生产商处理这个问题的典型方式是将成本和努力推给API消费者。但这并不具有规模,尤其是在客户为使用你的API的权利付费的情况下。每一个突破性的变化都会增加消费者使用你的API的成本和负担,如果有一个竞争对手能够以更低的成本提供服务,你就会失去这些客户。

在互联网的历史上,可扩展的解决方案是设计支持向后兼容的变化的服务和API,避免破坏消费者。TCP/IP、HTTP和HTML都是这种对非破坏性变化的承诺的伟大例子。

通过采用 "API的希波克拉底誓言 "和坚持对API消费者 "首先,不伤害 "的原则--以及 "向后兼容的三个规则"--你可以在你的组织内引入实践,以支持随时间变化的同时避免破坏API消费者。

最后,在你无法避免破坏变化的情况下,你可以采用并排部署的方式来隔离破坏,减少API客户应用的变化负担。

随着我们越来越多的商业活动通过API处理,那些认识到这一挑战并满足这一需求的公司将处于成功的有利地位。

New call-to-action

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值