本设计指南的目标是帮助开发者设计简单、一致且易用的网络 API。同时,它还有助于将基于套接字的 RPC API 与基于 HTTP 的 REST API 的设计融合在一起。
RPC API 通常根据接口和方法设计。随着时间的推移,接口和方法越来越多,最终结果可能是形成一个庞大而混乱的 API 接口,因为开发者必须单独学习每种方法。显然,这既耗时又容易出错。
引入 REST 架构风格主要是为了与 HTTP/1.1 配合使用,但也有助于解决这个问题。其核心原则是定义可以用少量方法控制的命名资源。这些资源和方法被称为 API 的“名词”和“动词”。使用 HTTP 协议时,资源名称自然映射到网址,方法自然映射到 HTTP 的 POST
、GET
、PUT
、PATCH
和 DELETE
。这使得要学习的内容减少了很多,因为开发人员可以专注于资源及其关系,并假定它们拥有的标准方法同样很少。
HTTP REST API 在互联网上取得了巨大成功。2010 年,大约 74% 的公共网络 API 是 HTTP REST(或类似 REST)的 API,大多数 API 均使用 JSON 作为传输格式。
虽然 HTTP/JSON API 在互联网上非常流行,但它们承载的流量比传统的 RPC API 要小。例如,美国高峰时段大约一半的互联网流量是视频内容,显然出于性能考虑,很少有人会使用 HTTP/JSON API 来传送此类内容。在数据中心内,许多公司使用基于套接字的 RPC API 来承载大多数网络流量,这可能涉及比公共 HTTP/JSON API 高几个数量级的数据(以字节为单位)。
在实际使用中,人们会出于不同目的选择 RPC API 和 HTTP/JSON API,理想情况下,API 平台应该为所有类型的 API 提供最佳支持。本设计指南可帮助您设计和构建符合此原则的 API。它将面向资源的设计原则应用于通用 API 设计并定义了许多常见的设计模式,从而提高可用性并降低复杂性。
什么是 REST API?
REST API 是可单独寻址的“资源”(API 中的“名词”)的“集合”。资源通过资源名称被引用,并通过一组“方法”(也称为“动词”或“操作”)进行控制。
REST Google API 的标准方法(也称为“REST 方法”)包括 List
、Get
、Create
、Update
和 Delete
。API 设计者还可以使用“自定义方法”(也称为“自定义动词”或“自定义操作”)来实现无法轻易映射到标准方法的功能(例如数据库事务)。
设计流程
设计指南建议在设计面向资源的 API 时采取以下步骤(更多细节将在下面的特定部分中介绍):
- 确定 API 提供的资源类型。
- 确定资源之间的关系。
- 根据类型和关系确定资源名称方案。
- 确定资源架构。
- 将最小的方法集附加到资源。
资源
面向资源的 API 通常被构建为资源层次结构,其中每个节点是一个“简单资源”或“集合资源”。 为方便起见,它们通常被分别称为资源和集合。
- 一个集合包含相同类型的资源列表。 例如,一个用户拥有一组联系人。
- 资源具有一些状态和零个或多个子资源。 每个子资源可以是一个简单资源或一个集合资源。
例如,Gmail API 有一组用户,每个用户都有一组消息、一组线程、一组标签、一个个人资料资源和若干设置资源。
虽然存储系统和 REST API 之间存在一些概念上的对应,但具有面向资源 API 的服务不一定是数据库,并且在解释资源和方法方面具有极大的灵活性。例如,创建日历事件(资源)可以为参与者创建附加事件、向参与者发送电子邮件邀请、预约会议室以及更新视频会议时间安排。
方法
面向资源的 API 的关键特性是,强调资源(数据模型)甚于资源上执行的方法(功能)。典型的面向资源的 API 使用少量方法公开大量资源。方法可以是标准方法或自定义方法。对于本指南,标准方法有:List
、Get
、Create
、Update
和 Delete
。
如果 API 功能能够自然映射到标准方法,则应该在 API 设计中使用该方法。对于不会自然映射到某一标准方法的功能,可以使用自定义方法。自定义方法提供与传统 RPC API 相同的设计自由度,可用于实现常见的编程模式,例如数据库事务或数据分析。
示例
以下部分介绍了如何将面向资源的 API 设计应用于大规模服务的一些实际示例。您可以在 Google API 代码库中找到更多示例。
在这些示例中,星号表示列表中的一个特定资源。
Gmail API
Gmail API 服务实现了 Gmail API 并公开了大多数 Gmail 功能。它具有以下资源模型:
- API 服务:
gmail.googleapis.com
- 用户集合:
users/*
。每个用户都拥有以下资源。- 消息集合:
users/*/messages/*
。 - 线程集合:
users/*/threads/*
。 - 标签集合:
users/*/labels/*
。 - 变更历史记录集合:
users/*/history/*
。 - 表示用户个人资料的资源:
users/*/profile
。 - 表示用户设置的资源:
users/*/settings
。
- 消息集合:
- 用户集合:
Cloud Pub/Sub API
pubsub.googleapis.com
服务实现了 Cloud Pub/Sub AP,后者定义以下资源模型:
- API 服务:
pubsub.googleapis.com
- 主题集合:
projects/*/topics/*
。 - 订阅集合:
projects/*/subscriptions/*
。
- 主题集合:
Cloud Spanner API
spanner.googleapis.com
服务实现了 Cloud Spanner API,后者定义了以下资源模型:
- API 服务:
spanner.googleapis.com
- 实例集合:
projects/*/instances/*
。每个实例都具有以下资源。 - 操作的集合:
projects/*/instances/*/operations/*
。 - 数据库的集合:
projects/*/instances/*/databases/*
。 每个数据库都有以下资源。- 操作的集合:
projects/*/instances/*/databases/*/operations/*
。 - 会话集合:
projects/*/instances/*/databases/*/sessions/*
。
- 操作的集合:
- 实例集合: