云服务器价格_云数据库_云主机【优惠】最新活动-搜集站云资讯

香港带宽_免费云服务器哪家好_企业级

小七 141 0

作为基础设施的api:具有版本控制的防将来攻击的条纹

说到api,改变并不流行。虽然软件开发人员习惯于快速、频繁地迭代,但只要有一个用户开始使用他们的接口,API开发人员就会失去这种灵活性。我们很多人都熟悉Unix操作系统是如何演变的。1994年,Unix Haters手册出版,其中包含了一长串关于该软件的信件,从为电传打字机优化的过于隐晦的命令名,到不可逆转的文件删除,再到有太多选项的非直观程序。二十年过去了,这些投诉中的绝大多数仍然有效,即使是在几十种现代衍生品中。Unix已经得到了广泛的应用,改变它的行为将具有挑战性的意义。不管是好是坏,它与用户建立了一个合同,定义了Unix接口的行为方式。类似地,API表示一个通信契约,如果没有大量的合作和努力,就不能更改它。因为有太多的企业依赖Stripe作为基础设施,我们从Stripe开始考虑这些合同。到目前为止,自2011年公司成立以来,我们一直保持与API的每个版本的兼容性。在本文中,我们将分享如何在Stripe上管理API版本。为与API集成而编写的代码中有一些固有的期望。如果端点返回一个名为verified的布尔字段以指示银行帐户的状态,则用户可能会编写如下代码:如果银行账户[:已验证]...其他的...结束如果我们后来用一个可能包含已验证值的状态字段替换银行帐户的已验证布尔值(就像我们在2014年所做的那样),代码将中断,因为它依赖于一个不再存在的字段。这种改变是向后不兼容的,我们避免做出改变。以前存在的字段应保持存在,并且字段应始终保持其相同的类型和名称。但并非所有的更改都是向后不兼容的;例如,可以安全地添加一个新的API端点,或者将一个新字段添加到以前从未出现过的现有API端点。有了足够的协调,我们也许能够让用户知道我们将要做的更改,并让他们更新他们的集成,但即使这是可能的,也不会非常方便用户。就像连接的电网或供水系统一样,连接后,API应该尽可能长时间不间断地运行。我们在Stripe的使命是为互联网提供经济基础设施。就像电力公司不应该每两年改变一次电压一样,我们相信我们的用户应该相信webapi会尽可能稳定。API版本控制方案允许webapi向前发展的一种常见方法是使用版本控制。用户在发出请求时指定一个版本,API提供者可以对下一个版本进行所需的更改,同时保持当前版本的兼容性。随着新版本的发布,用户可以在方便的时候进行升级。这通常被视为一种主要的版本控制方案,其名称为v1、v2和v3,这些名称作为URL的前缀(如/v1/widgets)或通过Accept这样的HTTP头进行传递。作为一个大的版本,它的负面影响几乎是从零开始的。这也不是一个明显的胜利,因为会有一类用户不愿意或无法升级,陷入旧的API版本中。然后,提供商不得不做出一个艰难的选择,要么退出API版本,要么通过扩展切断这些用户,要么以相当大的成本永远维护旧版本。虽然让提供商维护旧版本乍一看可能对用户有利,但他们也在以减少改进进度的形式间接支付费用。工程时间被转移到维护旧代码上,而不是开发新特性。在Stripe,我们使用滚动版本来实现版本控制,滚动版本以发布日期命名(例如,2017-05-24)。虽然向后不兼容,但每一个都包含一组小的更改,这些更改使增量升级相对容易,以便集成可以保持最新状态。用户第一次发出API请求时,他们的帐户会自动固定到最新的可用版本上,从那时起,他们进行的每个API调用都会隐式地分配该版本。这种方法保证了用户不会意外地收到一个破坏性的更改,并通过减少必要的配置量使初始集成变得不那么痛苦。用户可以通过手动设置条带版本标头来覆盖任何单个请求的版本,或者从Stripe的仪表板升级其帐户的固定版本。一些读者可能已经注意到,stripeapi还使用前缀路径(如/v1/charges)定义主要版本。虽然我们保留在某个时候使用这个的权利,但它在一段时间内不太可能改变。如上所述,主要的版本更改往往会使升级变得痛苦,我们很难想象一个API重新设计的重要性足以证明这种用户影响的合理性。在过去的六年里,我们目前的方法已经足够支持几乎一百个向后不兼容的升级。引擎盖下的版本控制版本控制总是在改进开发人员体验和维护旧版本的额外负担之间进行折衷。我们努力实现前者,同时最小化后者的成本,并实现了一个版本控制系统来帮助我们实现这一点。让我们快速了解一下它是如何工作的。条带API的每个可能的响应都由一个我们称为API资源的类进行编码。API资源使用DSL定义其可能的字段:ChargeAPI资源类必需:id,String必选:金额,整数结束编写API资源是为了使它们描述的结构与当前版本的API相同。当我们需要进行向后不兼容的更改时,我们将其封装在版本更改模块中,该模块定义有关更改、转换和可修改的API资源类型集的文档:类CollapseEventRequest数据[:request][:id])结束结束结束在其他地方,版本更改会分配给主列表中相应的API版本:类版本更改版本={2017年5月25日[更改::AccountTypes,更改::CollapseEventRequest,更改::EventAccountToUserID],'2017-04-06'=>[更改:LegacyTransfers],'2017-02-14'=>[更改::AutoexpandChargeDispute,更改::AutoexpandChargeRule],'2017-01-27'=>[更改::SourcedTransfersOnBts],...}结束编写版本更改的目的是希望它们能够自动从当前API版本向后应用,并且按顺序进行。每一个版本变更都假定,尽管新的变更可能存在于它们前面,但是它们接收到的数据看起来与最初编写时相同。生成响应时,API首先通过描述当前版本的API资源来格式化数据,然后从以下其中之一确定目标API版本:条带版本标头(如果已提供)。授权的OAuth应用程序的版本(如果请求是代表用户发出的)。用户的固定版本,在用户第一次请求条带时设置。然后它回溯时间,应用每个版本更改模块,直到达到目标版本为止。请求在返回响应之前由版本更改模块处理。版本更改模块将旧的API版本从核心代码路径中抽象出来。开发人员在开发新产品时,基本上可以避免考虑它们。有副作用的变化大多数向后不兼容的API更改都会修改响应,但情况并非总是如此。有时需要一个更复杂的更改,它会从定义它的模块中泄漏出来。我们给这些模块分配了一个has_side_effects注释,它们定义的转换变成了no op:类LegacyTransfers