Slack是一种可以把各种碎片化的企业沟通和协作集中到一起(类似钉钉):
多年来,我们始终牢记的一件事是为出色的开发人员体验而设计。虽然我们可以在幕后更改我们功能的实现,但删除或更改现有 API 的行为契约是非常困难的。这就是为什么从一开始就仔细考虑您的 API 设计很重要。
如果 API 设计得很好,开发人员会喜欢它们,并且可以成为使用您的 API 的最具创意的创新者。他们会投入巨资,有时甚至会成为您 API 的传道者。我们还重视开发人员在我们的平台上进行构建所花费的时间和资源。糟糕的 API 设计会导致采用率最低,甚至令人沮丧。糟糕的 API 成为公司的负担。
在这篇文章中,我们将描述我们的 API 设计原则,以及我们如何规范、审查和测试新 API 的过程。最后,您应该有一些想法可以带回您自己的 API 流程。
设计原则
专注于单一设计并保持 API 简单。简单的 API 不仅易于理解,而且更易于扩展、性能更高且更安全。此外,向 API 添加新功能很容易,但很难删除它们。
在某些情况下,我们不得不将现有的复杂 API 分解为更简单、更专注的 API。随着时间的推移,我们最受欢迎的 API 方法之一rtm.start变得非常昂贵。此方法将返回一个 URL 以连接到我们的 websocket API 以及有关团队、其频道和其成员的各种数据。随着团队规模的增长,这种有效载荷变得笨拙而庞大,这对于开发人员来说处理起来很昂贵。
尽管少数开发人员使用了此方法返回的数据,但大多数开发人员只想连接到 WebSocket。因此,Slack 引入了一种新的 API 方法,rtm.connect它只做一件事:返回一个 WebSocket API 会话 URL,而不返回负载中的任何其他数据。这种新方法帮助应用程序开发人员和 Slack 替代了rtm.start.
这个特定故事的一个要点是:当有疑问时,在任何集合中强制执行有限数量的对象或对它们进行分页。定义合理、合理的上限并不是过早的优化。当您让有机增长向您展示这些界限的位置时,将它们包含在更合理的范围内要困难得多。
对于开发人员来说,能够理解您的 API 并快速入门非常重要。您希望确保不熟悉您的 API 的开发人员可以在合理的时间内完成“Hello world”练习。您可以用来评估这一点的一个指标是“第一个 Hello World 时间”。
在 Slack,我们希望入门级开发人员能够在大约 15 分钟内了解该平台、创建应用程序并发送他们的第一个 API 调用。您的目标“第一个 Hello World 时间”将根据您运行的平台和您的开发人员受众的经验水平而有所不同。
入门指南、教程、示例代码和交互式文档对帮助开发人员快速入门大有帮助。在 Slack,除了入门指南和教程之外,我们的文档还包括一个交互式 API 测试器,开发人员可以在其中试用浏览器中的任何 API 端点。我们甚至开始编入多种语言的代码片段,这些代码片段可以使用我们不断增长的 SDK 集合轻松插入到代码中。
您希望您的 API 直观一致。这应该反映在您的端点名称、输入参数和输出响应中。即使不阅读文档,开发人员也应该能够猜出您的 API 的一部分。它应该像他们已经知道的那样工作。有3个级别的一致性:
- 与行业标准的一致性:它应该尽可能地遵守行业中公认的最佳实践。
- 与您的产品的一致性:您应该根据您在产品中对这些概念的称呼来选择字段名称。避免使用缩写词、首字母缩略词和行话。详细点。
- 与您的其他 API 方法的一致性:您在不同 API 方法中使用的名称应该彼此一致。
实现一致性的最佳方法之一是巩固和写下您对 API 设计的看法,尤其是在没有单一正确或错误的方法时。选择一边并坚持下去。在 Slack,我们编写了全面的 API 设计指南,定义了我们为 API 遵循的一致实践和模式。
设计 API 的另一个原则是返回有意义的错误,使开发人员更容易进行故障排除。在 API 设计过程中,工程师往往很少关注 API 返回的错误。不正确或不清楚的错误令人沮丧,并可能对 API 的采用产生负面影响。开发人员可能会陷入困境并放弃。好的错误易于理解、明确且可操作。它们将帮助开发人员了解问题以及如何解决它。实现细节不应泄漏到您的 API 中,尤其是错误。
除了返回错误代码之外,在文档中或 API 响应中的其他地方添加更长格式的错误通常很有用。这些可以包括人类可读的错误描述,包括如何解决问题或链接到更多信息。
糟糕的设计会限制性能。因此,在设计 API 时,您应该确保以下几点:
- 对大型集合进行分页:API 通常需要处理大型数据集。API 调用最终可能会返回数千个项目。这可能会使 Web 应用程序后端过载,甚至会降低无法处理大型数据集的客户端的速度。因此,对任何大型结果集进行分页非常重要。
- 不要在其他大集合中嵌套大集合:在这种情况下,分页太复杂了。
- 限制您的 API 的速率:您不希望一个行为不端的开发人员或失控的代码循环导致您的应用程序宕机。为了在提高应用程序的可靠性和可用性的同时保护基础设施,您应该添加合理的速率限制。
Slack 的一个 API channels.list(现已停用)用于返回频道列表和每个频道中的所有成员——本质上是将一个集合嵌套到另一个中。Slack 诞生时,我们假设每个团队仅限于几百名用户。然而,随着产品的发展和成长,这种假设不再成立。我们开始拥有拥有数万用户的团队。那时,这种需要在同一个 API 调用中为每个通道返回所有通道和成员的结构变得难以支持。然后我们将其分解为两个不同的、更简单的 API:conversation.list和conversation.members 。这不仅有助于提高我们的 API 性能,还有助于改善开发人员体验。
在发布产品的新更新时,您最不想发生的事情是因为 API 更改而破坏客户的代码。那么,什么是突破性的变化?任何可以阻止现有应用程序像更改之前一样运行的更改。
在 Slack,我们遵循的理念是昨天有效的方法明天有效。也就是说,改变是不可避免的。在极少数和特殊情况下,我们决定引入重大更改。给予多少通知以及我们将在多长时间内为开发人员提供流畅的体验取决于许多因素,例如受影响的用户和工作区的数量以及开发人员处理的难度。您不想每隔几个月就要求相同的开发人员处理重大更改。
设计流程
除了明确定义的 API 设计指南,我们还有严格的 API 设计流程,使 Slack 的任何团队都可以构建公共 API。以下是我们遵循的步骤:
一旦团队确定了他们想要解决的问题并定义了 API 的用例,我们就会开始编写 API 规范。该规范描述了开发人员将使用的 API 的各个方面。这可能包括方法名称、目的、示例请求、响应和可能的错误等信息。规范让我们有机会彻底思考 API 设计。它还充当中心草案,使每个人都对我们的目标以及我们的资源如何公开保持一致。
在编写任何代码 之前发现您的设计问题会更有效率。
在 Slack,在编写 API 规范后,工程师在名为#api-decisions的内部 Slack 频道中分享它们. 对于构建 API 的工程师来说,这是一个机会,可以从由来自开发人员关系、工程、产品管理、开发人员支持、合作伙伴工程和安全部门的人员组成的跨职能小组对他们的提案获得不同的观点。如果更改需要更深入的讨论,我们会在定期安排的 API 办公时间内进行审核。在这些会议期间,该小组讨论了诸如“引入的更改是否与我们现有的其他 API 一致?”以及“它们是否与我们的 API 设计指南一致?”等主题。该小组还深入研究了更改的命名、可用性、安全性和性能考虑因素。
我们还与内部利益相关者一起向合作伙伴提供我们的 API 规范草案,他们是我们实现 API 的理想开发人员。他们的反馈对于验证 API 是否解决了它应该解决的问题以及帮助我们了解 API 需要改进的方面至关重要。通过在编写任何代码之前寻求这些反馈,我们可以快速迭代 API 设计并构建更好的 API。
在我们广泛提供新 API 之前,我们会为选定的合作伙伴提供早期访问权限。这些合作伙伴将我们的 API 集成到他们的产品中,并向我们提供有关 API 的详细反馈。这为我们提供了一个额外的机会,可以在公开发布之前进一步改进 API 设计并修复任何已识别的问题。
结束语
设计直观、一致且易于使用的 API 很困难。在这篇文章中,我们介绍了 API 设计原则和我们在 Slack 遵循的设计过程。当您构建 API 时,一些关键要点是:花时间预先考虑您的 API 设计,有意识地选择您的设计,并收集来自多个利益相关者的反馈。