关掉你的旧API的正确方法

image

所有事情都会有结束的时候,即使是HTTP APIs。无论今天你的API有多好,总有一天会发布一个全新的版本,一个有提升但不能兼容旧端点的版本,一个能更好地解决相同问题的新参数的版本,或者完全关闭你的API。总之你目前的API不会永远存在。

但不方便的是,你的API有客户端。如果你在没有适当警告他们的情况下关闭端点、参数或整个api,那么用户将非常生气。

如何安全地关闭你的API,并让你的用户尽可能地轻松看待这件事呢?

有一些正确的方法可以做到这一点,包括令人振奋的新的IETF "Building Blocks for HTTP APIs"工作组标准化的两个新的标题草案,它旨在帮助实现这一确切的过程。让我们来看一看。

制定一个计划

首先:检查相关的API是否真的有链接任何客户端。

希望你有一些API指标,或者至少在某处有日志记录。如果你没有,那就添加一些吧 !如果你有,而且可以确定没有人在使用这个API,那就太好了。现在就把它关掉,删除代码,跳过这篇文章,睡个好觉吧。

下一个问题,如果你没有打瞌睡的话,就问问你自己,除了关闭这个API,还有没有其他的选择。因为你关闭的所有东西都会破坏别人的代码并需要他们花时间来修复。如果API继续工作,这对你的客户生态系统和整个网络是有好处的。

在许多情况下,旧的API可以在内部进行转换,以透明的方式将请求转换为对新API的调用,而不需要维护两个完全独立的版本。这是 Stripe API版本化方法的一个基本部分,它包括对所有API更改的转换,以确保对不兼容的旧版本的请求能继续像以前一样工作,自动地转换请求和响应以根据需要使用更新的代码。

像这样的转换并不是总是可能的,而且一直这样做会带来显著的额外复杂性,但如果你能做到,这可以为你的用户提供一个有价值的稳定性,并避免很多废弃旧版本或维护旧版本所需的工作。

但是,如果在生产中使用了这个服务/端点/参数,并且继续支持它是不实际的,就必须结束它。

要做到这一点,你需要一个计划。首先要问三个关键问题。

  • 你希望客户端使用它来做什么? 常见的答案包括:
    • 更新到较新的同一事物仍然支持的版本。
    • 使用一些其他的替代端点/参数/服务来代替。
    • 使用不同的服务,他们是独立的,你不关心。
  • 他们应该什么时候开始从这个API迁移出去?你提议的替代方案今天就可以使用了吗?
  • 最后期限是什么?也就是说,这个API什么时候会完全停止工作?(如果你还不完全确定,你可以把这个答案推迟一下)。

一旦你有了一个计划,就该把它告诉大家了。

沟通

首先:告诉大家。

在你的邮件列表上发邮件,并将其发布到Twitter上,如果你有API规范,更新它们(例如,OpenAPI有一个关于操作参数deprecated 字段 ),并在网上的相关文档中着重强调这一点。

你应该概括上述所有信息:他们应该做什么,你建议他们何时开始迁移,以及他们必须迁移的最后期限(如果你有最后期限的话)。

一旦你告诉了大家,就该告诉计算机了。这就是新的IETF header文件的作用。

The Deprecation Header

Deprecation header告诉客户端他们所请求的资源仍然可以像以前一样工作,但不再被推荐使用。你可以用一个HTTP header非常简单地说明这一点。

Deprecation: true

或者,你也可以提供一个日期。这个日期用来告诉用户他们应该何时开始迁移到其他地方。日期可以是过去(如果他们应该立即开始迁移)或未来(通常意味着他们应该迁移的东西还没有准备好)。就像这样:

Deprecation: Thu, 21 Jan 2021 23:59:59 GMT

如果你要废弃整个端点或服务,你可以在每个响应中返回此值。如果你正在废除一个特定的功能,也许是一个参数、一个请求方法或者请求体中的某个字段,然后当使用该特定功能时,你需要在请求中只返回这个功能。

为了给客户端提供更多的信息,你可以使用 Link HTTP响应header来链接到端点或其他地方的可读文档。你可以在同一个 Link header中组合包含多个此类文件,只需用逗号隔开它们(我们稍后会看到一个完整的例子)。该规范定义了4个与废弃有关的链接。

弃用链接

你可以像这样链接到一个可供人阅读的废弃描述:

Link: <https://developer.example.com/deprecation>;
 rel="deprecation"; type="text/html"

这是告诉你的用户发生了什么,以及他们应该做什么的主要方式。你几乎总是想使用这个方式! 如果你还没有完整的细节和最终的关闭日期,那么即使是一个占位符也会有帮助。在这种情况下,不要忘记让用户用邮件列表或RSS或类似的方式订阅更新,这样他们就可以在完整的计划就绪后获悉它。

最新版本的链接

如果你想让客户端移动到你的API的同一端点的最新版本,使用以下方式指明,像这样:

Link: <https://api.example.com/v10/customers>;
 rel="latest-version"

后续版本链接

如果你有多个版本的API可用,通常最好是一次向前迁移一个版本,而不是直接从最早的已废弃的版本跳到最新的版本。为了帮助解决这个问题,你可以链接到被废弃的端点的下一个版本,而不仅仅是最新的版本,像这样:

Link: <https://api.example.com/v2/customers>;
 rel="successor-version"

替代链接

如果没有这个API的新对等版本,用户应该迁移到一个完全不同的但可能是一个很好的替代的资源,你可以使用替代链接指出:

Link: <https://api.example.com/v2/users/123/clients>; 
rel="alternate"

The Sunset Header

一旦你知道API何时会完全关闭,你就应该添加一个Sunset header

Sunset header告诉客户端什么时候会停止工作。这是一个硬性期限:API客户必须在这个日期之前转移到其他地方,而且你会承诺在这之前不会破坏任何东西。

你必须在这里提供一个日期,而且它应该是在未来。如果是在过去,那也没关系:在这一点上,你实际上是在说 “这可能随时会关闭,你需要立即停止使用它”。它看起来像这样:

Sunset: Tue, 20 Jul 2021 23:59:59 GMT

这是很简单的,而且不仅仅可以用于API关闭:你可以用它来表示将在未来的URL迁移中出现的HTTP重定向,或者表示某些URL的有限寿命(出于那些临时性质的内容,或者出于监管的原因,如某些资源的数据保留政策)。它说的是 “这个端点可能在这个日期之后停止做你所期望的事情,请做好准备”。

Sunset链接

本规范还提供了一个 sunset 链接关系。此链接旨在链接到关于你关闭这个特定端点的计划的更多信息(可能与你的deprecation链接一样的文档,如果你有的话)或关于你的服务的一般sunset 政策。就像这样:

Link: <http://developer.example.com/our-sunset-policy>;
rel="sunset";type="text/html"

这是一个指出一般sunset政策是一个非常有用的东西的好地方。sunset 政策告诉客户,当你关闭端点时(例如,在替代者上线一年后),用户应该如何确保他们听到这个消息(邮件列表、状态页、HTTP headers,你说了算),他们通常应该怎么做(更新、检查文档、关注 Link header)。

现在添加一个sunset政策对deprecation没有太大帮助,但是如果你在一年前发布了一个,那么你的客户端就已经做好准备了。发布sunset/deprecation政策的第二个最佳时机是现在。如果您正在编写deprecation文档,那么可能值得考虑。

配合工作

这些部件被设计得配合得很好。例如,为了表明一个API最近被废弃,将在6个月后关闭,链接到文档,并提供一个通往下一版本的直接链接,你应该在响应中包含header,像这样:

Deprecation: Thu, 21 Jan 2021 23:59:59 GMT
Sunset: Tue, 20 Jul 2021 23:59:59 GMT
Link: <https://api.example.com/v2/customers>; rel="successor-version",
    <https://developer.example.com/shutting-down-customers-v1>; rel="deprecation"

渐进式关闭

一旦所有这些都准备就绪,而且你的sunset期限已过,你就可以走了。

但这并不意味着你需要立即完全关闭API。渐进式关闭可以帮助确保任何仍在使用该API的客户端在它完全消失之前得到最后的警告。GitHub在2018年删除一些加密支持时就是这样做的:首先他们禁用一小时,然后重新启用,然后在两周后永久禁用。

也有其他技巧:安卓系统在2015年为废弃的本地API增加了越来越多的延迟,最终上升到整整16秒的等待,最后才完全关闭API。这些渐进式关闭为错过最后期限的客户提供了一点灵活性,并可能帮助那些没有注意到deprecation spot的客户在API完全关闭之前发现并处理这个问题。

翻转开关

无论哪种方式,一旦你做好了最好的沟通,就该关闭端点/功能/整个服务,删除代码,最后休息一下了。

像这样小心翼翼地进行废弃和关闭,可以让你的客户尽可能清楚地了解他们如何依赖你的API,他们何时需要采取行动,以及他们需要做什么。这些变化可能是个大问题,这些信息很重要!

这些新的草案header使我们不仅可以与人类沟通,而且还可以将这些信息暴露给自动化系统。随着这些header的普及,我非常高兴地看到更多的工具开始在它们之上构建。通用的HTTP客户端可以根据这些数据自动记录有用的警告,API生成器本身可以根据API规范为您处理越来越多的此类问题,而 HTTP Toolkit 等HTTP调试器可以在截获的实时流量中为您突出显示已弃用的端点的使用。这是一个令人兴奋的时刻,可以开始关闭一些东西了。

需要注意的是,这些header是HTTP规范草案。 它们有可能在最终确定之前发生变化。也就是说,它们已经经历了几轮修订,从现在开始,它们不太可能有大的变化,现在是时候开始在野外测试它们了。

这确实意味着仍有时间进行反馈。如果你对如何工作以及如何更好地工作有想法,请与 "Building Blocks for HTTP APIs "工作组联系。你可以给邮件列表发邮件:httpapi@ietf.org,或者在这里滚动查看以前的邮件列表讨论。

调试、集成或构建HTTP APIs?使用 HTTP Toolkit .,可以从任何地方一键拦截、检查和模拟HTTP。

作者于 3 个月前发表 Tim Perry