作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
乔丹·安布拉的头像

约旦Ambra

以前的雇主包括可口可乐, Concentra, 和VMWare, 乔丹是一位一流的建筑师, 开发人员, 系统管理员, 和企业家.

专业知识

以前在

可口可乐
分享

你是否发现自己在想 “他们在想什么??” 当通过其API集成web服务时? If not, 你’ve been far luckier than I have.

任何软件开发人员都知道,让一个项目变成意大利面条式代码是多么容易, web APIs are no less prone to resulting in a tangled web. 但它不需要这样. 事实上,设计是可能的 伟大的 web api,人们会 享受 using, that 你’ll 享受 creating 也。. 但是什么是好的API呢? 在本文中,我们将回答这个问题,揭示如何设计一个好的API.

的角度来看

Most of the time when 你’re building solutions, 你’re designing for end 用户s who are not 程序员, or who are generally not technically sophisticated. You’re giving them a graphical interface and, 如果你一直做好你的工作, 你已经从他们那里收集了一个非常好的想法,他们需要这个接口做什么.

API开发 是不同的. When designing an API, 你’re designing an interface for 程序员, probably without even knowing who they are. 不管他们是谁, 他们会有技术上的成熟(或者至少会认为他们有技术上的成熟)来指出您软件中的每一个小缺陷. 你的用户对你的API系统设计可能会像你对他们一样挑剔, 并且会非常喜欢批评它.

And therein lies part of the irony, by the way. If 任何人 should 理解 how to make a web API that’s easy-to-use, it’s . 毕竟, 你’re a software engineer just like the 用户s of 你的 API, 所以你分享他们的观点. 你不?

好吧,当你当然 理解 他们的观点,你不一定 分享 他们的观点. 当你在发展或提高 你的 你有一个API的透视图 设计师 whereas they have the perspective of an API 用户.

API的设计师 通常关注这样的问题 “这项服务需要做什么?” or “这项服务需要提供什么?”,而 API用户 专注于 “我如何使用这个API来做我需要的事情?”或者更准确地说, “我怎样才能花最少的努力从这个API中得到我需要的东西?”.

这些不同的问题引出了两种截然不同的观点. As a result, the necessary prerequisite to designing a 伟大的 API是将您的视角从API设计者的视角转变为API用户的视角. 换句话说, 不断地问自己,如果你是自己的用户,你自然会问的问题. 而不是考虑你的API 可以 do, think about the different ways it may need or 想要 to be 使用 然后专注于让这些任务对你的API用户来说尽可能简单.

虽然这听起来简单明了, 令人惊讶的是,api很少以这种方式设计. Think about the APIs 你’ve encountered in 你的 career. 它们在设计时是否经常考虑到这种观点? Following web API design best practices 可以 be challenging.

So with that said, let’s proceed and talk about the 5 Golden Rules for 设计ing a Great 网络 API,即:

  1. 文档
  2. 稳定性和一致性
  3. 灵活性
  4. 安全
  5. 易于采用

规则1:文档

文档. 是的,我从这里开始.

你讨厌文档吗?? 好吧, 我能感同身受, 但是戴上“用户视角”的帽子,我敢打赌,比起编写文档,你更讨厌的一件事是不得不尝试使用一个没有文档的API. 我说完我的理由.

底线是,如果您希望任何人使用您的API,文档是必不可少的. 你只需要把这件事做好. 这是用户看到的第一件事,所以在某种程度上,它就像礼品包装. 呈现良好,人们更有可能使用您的API并忍受任何特性.

那么我们如何编写好的文档呢?

的 relatively easy part is documenting the API methods themselves; i.e.,示例请求和响应,以及对两者中每个元素的描述. 幸运的是, 有越来越多的软件工具可以促进和简化生成文档的任务. Or 你 可以 write something 你的self that introspects 你的 API, 端点, 和功能, generates the corresponding documentation for 你.

但是区分优秀文档和适当文档的是使用示例和, 在理想的情况下, 教程. 这有助于用户理解您的API以及从哪里开始. It orients them and helps them load 你的 API into their brain.

例如,如果开发者 为什么Twilio 我们要列出每一类吗, 每一个方法, 以及所有可能的API响应, but didn’t bother to mention that 你 可以 send an SMS, 追踪电话, 或者通过他们的API购买电话号码, API用户要花很长时间才能找到并理解这些信息. 你能想象在一个巨大的类和方法树中排序而不了解它们的用途吗, 除了他们的名字? 听起来很可怕,对吗?? 但 that’s exactly what so many API providers do, thereby leaving their APIs opaque to anybody but themselves. 的 Rackspace CloudFiles 开发人员 and API guide is one such example; it’s difficult to get 你的 bearings unless 你 already 理解 what they’re doing and what they’re providing.

因此,编写简洁的教程,帮助开发人员快速上手并运行, with at least a skeleton of what they’re trying to do, then point them in the direction of the more detailed, 完整文档的功能列表,以便他们可以扩展他们所拥有的功能.

一旦你完成你的文档, 一定要确认它对别人来说是有意义的,而不是你自己. Send it out to other 开发人员s in 你的 network, 不要给他们任何指示,而要他们参考文档, 并要求他们在15分钟内遵循教程或构建一些真正基础的东西. 如果他们不能在15分钟内完成与你的API的基本集成,你还有更多的工作要做.

有关一些值得注意的优秀和详细文档示例,请查看 为什么Twilio, Django, MailChimp的. 这些产品都不一定是市场上最好的(尽管它们都是好产品)。, 然而,他们确实通过在市场中提供一些最好的文档来区分自己, 这当然促进了它们的广泛接受和市场份额.

规则2:稳定性和一致性

如果你用过 Facebook的应用程序接口,您知道他们经常弃用并完全重写他们的api. No matter how much 你 respect their hacker culture, 或者他们的产品, theirs is not a 开发人员-friendly perspective. 他们仍然成功的原因是他们拥有10亿用户, 不是因为他们的API很棒.

但你可能没有这么庞大的用户基础和市场份额, so 你’re going to need have a much less volatile API, 在相当长的一段时间内保持旧版本的运行和支持. 也许是几年. So toward that end, here are some tips and tricks.

Let’s say, for example, that 你的 API is accessible via the URL http://myapisite.com/api/widgets 并以JSON格式提供响应. 乍一看,这似乎没什么问题, 当您需要修改JSON响应的格式时会发生什么? Everyone that’s already integrated with 你 is going to break. 哦.

所以要提前做好计划, 从一开始就对API进行版本化, explicitly incorporating a version number into the URL (e.g., http://myapisite.com/api/widgets?版本= 1 or http://myapisite.com/api/widgets/v1),这样人们就可以依靠版本1工作,并可以升级到任何后续版本,当他们准备这样做. If 你 need to phase out a prior version at some point, 去吧, but give plenty of notice and offer some sort of transition plan.

A good URL scheme will include major versions in the URL. 对输出格式或支持的数据类型的任何更改都应该导致升级到新的主要版本. 一般, 如果您所做的只是在输出中添加键或节点,那么保持相同的版本是可以接受的, 但为了安全起见, 任何时候输出都会改变, 换一个版本.

除了随着时间的推移保持稳定之外,api还需要在内部保持一致. 我见过许多更改参数名称或post数据方法的api, depending on the endpoint that is being 使用. 而不是, 您应该在API中全局处理公共参数,并使用继承或共享架构在整个API中一致地重用相同的命名约定和数据处理.

最后, 您需要记录并发布变更日志,以显示API版本之间的差异,以便用户确切地知道如何升级.

规则3:灵活性

垃圾输入,垃圾输出(GIGO) 对大多数程序员来说是一个众所周知的口头禅吗. 应用于web API设计, 这个指导原则倾向于规定一种相当严格的请求验证方法. 听起来不错,对吧?? 没有混乱,没有问题.

Yet as with everything, there needs to be some balance. 因为不可能预测用户想要使用您的服务的每一种方式, since not every client platform is consistent (i.e.不是每个平台都有很好的JSON支持,一个不错的OAuth库,等等.), 对于输入和输出约束,最好至少有一定程度的灵活性或容忍度.

例如,许多api将支持各种输出格式,如JSON、YAML、XML等. al., but will only support specifying the format in the URL itself. 本着保持灵活性的精神,您也可以允许在URL中指定它(例如.g., / api / v1 /小部件.json),或者你也可以阅读和识别 接受:application / json HTTP header, or support a querystring variable such as ?= JSON格式等等.

既然我们这么做了, why not allow for the format specified to be case-insensitive, 所以用户可以指定 ?= json格式 也。? 这是减轻API用户不必要的挫败感的一个经典示例.

另一个例子是允许以不同的方式输入变量. 因此,就像您有多种输出格式一样,也允许有多种输入格式.g.、纯POST变量、JSON、XML等.). You should at least be supporting standard POST variables, many modern applications support JSON 也。, 所以这两个是很好的起点.

这里的要点是,您不应该假设每个人都与您有相同的技术偏好. With a little research into how other APIs work, 通过与其他开发者的对话, 您可以收集其他有用的有价值的替代方案,并将它们包含在您的API中.

规则4:安全性

安全性显然是构建到web服务中最重要的东西之一, but so many 开发人员s make it ridiculously hard to use. 作为API提供者, 您应该提供可用的示例,说明在访问API时如何进行身份验证和授权. 这应该不是一个最终用户花费数小时解决的难题. Make it 你的 goal that they either 不 have to write any code, or it takes them less than 5 minutes to write it.

对于大多数api,我更喜欢简单的 基于令牌的身份验证, 令牌是分配给用户的随机散列,如果被盗,他们可以在任何时候重置它. Allow the token to be passed in through POST or an HTTP header. 例如, the 用户 could (and should) send an sha - 1标记 作为POST变量, 或者以“Authorization: da39a3ee5e6b4b0d3255bfef95601890afd80709”的格式作为标头。.

Also, choose a secure token, not a short numeric identifier. 不可逆转的事情是最好的. 例如, 在用户创建期间生成SHA令牌并将其存储在数据库中相对简单. 然后,您可以简单地在数据库中查询与该令牌匹配的任何用户. 您还可以使用唯一标识符和盐值生成令牌,例如 沙(用户.ID + "abcd123"), then query for any 用户 that matches; e.g., where TokenFromPost = 沙(用户.ID + "abcd123").

另一个很好的选择是 OAuth 2 + SSL. 无论如何,您都应该使用SSL, but OAuth 2 is reasonably simple to implement on the server side, 库可用于许多常见的编程语言.

如果您所做的API应该可以通过JavaScript在公共网站上访问, 您还需要确保为令牌验证了每个帐户的url列表. 这种方式, nobody 可以 go inspect the calls to 你的 API, 从用户那里窃取令牌, 然后自己去用.

Here are some other important things to keep in mind:

  • 白名单功能. api通常允许您对数据执行基本的创建、读取、更新和删除操作. 但 你 不 想要 to allow these operations for every entity, so make sure each has a whitelist of allowable actions. 例如,确保只有授权用户才能运行以下命令 /用户/delete/. 类似的, 在用户请求中发送的所有有用的头也需要根据白名单进行验证. 如果您允许内容类型的标头, 验证用户发送的内容是否与支持的内容类型的while列表匹配. 如果没有,则返回一个错误消息,如406 Not Acceptable响应. 白名单很重要,因为很多api是自动生成的, 或者用黑名单代替, which means 你 have to be explicit about what 你 想要. 然而, the golden rule of security is to start with absolutely nothing, 并且只允许你 do 想要.

  • 保护自己免受 跨站请求伪造(CSRF). If 你 are allowing session or cookie authentication, 你需要确保你保护自己免受CSRF攻击. 的 Open 网络 Application 安全 Project (OWASP) 提供有用的指导: 排除这些漏洞的方法.

  • 验证对资源的访问. 在每个请求中, 您需要验证用户实际上是否被允许访问他们引用的特定项. 因此,如果您有一个端点来查看用户的信用卡详细信息(例如.g., / 152423 /账户/卡/视图), 确保ID“152423”引用的是用户真正被授权访问的资源.

  • 验证所有输入. All input from a 用户 needs to be securely parsed, 如果使用XML或JSON等复杂输入,最好使用知名库. Don’t build 你的 own parser, or 你’re in for a world of hurt.

规则5:易于采用

这是所有规则中最重要的一条,它建立在其他规则的基础上. 正如我在文档规则中提到的,与不熟悉您的API的人一起尝试. 确保它们至少可以使用您的API的基本实现来启动和运行, 即使只是跟随教程, 几分钟之内. 我认为15分钟是一个很好的目标.

这里有一些具体的建议,以简化和促进采用您的API:

  • 确保人们能够真正使用你的API,并且每次都能正常工作. 让新人偶尔尝试实现您的API,以验证它不会在某种程度上混淆您已经免疫的东西.

  • 保持简单. 不要做任何花哨的身份验证. 不要使用一些疯狂的自定义URL方案. Don’t reinvent SOAP, or JSON, or REST, or anything. 尽可能使用所有已经实现并被广泛接受的工具, so that 开发人员s only have to learn 你的 API, 而不是你的API + 10晦涩的新技术.

  • 提供特定于语言的库来与您的服务进行交互. 有一些很好的工具可以为您自动生成库,例如 羊驼 or Apache节俭. Currently 羊驼 supports Node, PHP, Python, Ruby. Thrift支持c++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, c#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml, 特尔斐 和更多的.

  • 简化任何必要的注册. If 你 are not developing an open source API, or if there is a signup process of any sort, 在注册时请确保这一点, a 用户 is very quickly directed to a tutorial. 并且使注册过程完全自动化,而不需要任何人工交互.

  • 提供出色的支持. A big barrier to adoption is lack of support. How will 你 handle and respond to a bug report? 文件不清晰怎么办?? 一个简单的用户? 论坛, bug追踪器, 电子邮件支持是很好的开始, but do make sure that when someone posts a bug, 你真的解决了这个问题. 没有人想看到一个鬼城论坛或一个巨大的尚未解决的漏洞列表.

网络 API概述

网络服务及其api比比皆是. Unfortunately, the vast majority are difficult to use. 原因包括糟糕的设计, 缺乏文件, 波动性, 未解决的bug, or, 在某些情况下, 以上都是.

遵循本文的指导将有助于确保你的web API是干净的, 证据确凿的, 和易于使用的. 这样的api非常罕见,因此更有可能被广泛采用和使用.

聘请Toptal这方面的专家.
现在雇佣
乔丹·安布拉的头像
约旦Ambra

位于 美国宾夕法尼亚州牛津市

成员自 2013年7月23日

作者简介

以前的雇主包括可口可乐, Concentra, 和VMWare, 乔丹是一位一流的建筑师, 开发人员, 系统管理员, 和企业家.

Toptal作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

专业知识

以前在

可口可乐

世界级的文章,每周发一次.

订阅意味着同意我们的 隐私政策

世界级的文章,每周发一次.

订阅意味着同意我们的 隐私政策

Toptal开发者

加入总冠军® 社区.