面向资源的设计
这篇设计指南的目的是帮助开发者设计出简单、一致、易于使用的网络 API,同时它也帮助我们统一了 RPC API(基于 socket)与 REST API(基于 HTTP)的设计。
传统上,人们参考像 CORBA 和 Windows COM 这样的 API 接口和方法来设计 RPC API。随着时间推移,越来越多的接口和方法被添加。最后的结果是被数量众多的接口和方法淹没,每一个都和其他不同。为了正确使用它们开发者必须仔细学习每一个接口或方法,这必定会消耗时间并容易引入问题。
REST 架构风格最早出现于2000年,主要设计为与 HTTP/1.1 一起使用。它的主要原则是定义能够被少量方法操作的命名资源。资源和方法被认为是 API 的名词和动词。与 HTTP 协议配合,资源名自然地映射为 URL,方法自然地映射为 HTTP 方法 POST
、GET
、PUT
、PATCH
和 DELETE
。
HTTP REST API 在互联网领域已经取得了巨大成功。在2010年,约 74% 的网络 API 是 HTTP REST API。
虽然 HTTP REST API 在互联网特别流行,但它们承载的流量却比传统的 RPC API 要少。例如,在美国高峰时期的约一半流量是视频内容,但因为效率问题,很少有人会考虑使用 REST API 来传输这些内容。在数据中心,许多公司使用基于 socket 的 RPC API 来传输大部分网络流量,这会比 REST API 高出几个数量级。
实际上,由于种种原因 RPC API 和 HTTP REST API 都是需要的。理想情况下一个 API 平台应该为所有 API 提供最好的支持。此指南将会帮助你设计并实现符合这一原则的 API。它将面向资源的设计原则应用到一般的 API 设计中,并且定义了许多通用的设计模式来提升可用性并降低复杂性。
注意:此设计指南解释了如何在独立于编程语言、操作系统或者网络协议的 API 设计中应用 REST 原则,而不是仅用于创建 REST API 的指南。
什么是 REST API?
REST API 被建模成可单独寻址的资源(API 的名词)的集合。资源通过它们的 资源名来引用,通过一小组方法(也被称为动词)来操作。
REST Google API 的标准方法(也叫 REST 方法)是 List
、Get
、Create
、Update
和 Delete
。当存在类似数据库事务这种不能被简单地映射到标准方法的需求时,API 设计者也可以使用自定义方法(也叫自定义动词或自定义操作 )。
注意:自定义动词不表示创造自定义的 HTTP 动词来支持自定义方法。对于基于 HTTP 的API,简单地映射到最合适的 HTTP 动词即可。
设计流程
此设计指南建议采用如下步骤来设计面向资源的 API(更详细的内容请参考后面的小节)
- 确定 API 提供的资源类型
- 确定资源间的关系
- 依据类型和关系来确定资源名方案
- 确定资源结构
- 为资源添加最少的方法集
资源
面向资源的 API 通常以资源层次进行建模,每一个节点是一个简单的资源或资源集合。方便起见,通常将它们称为资源和集合。
- 集合包含具有相同类型的资源列表。例如一个用户拥有联系人的集合
- 资源拥有一些状态和 0 个或多个子资源。每一个子资源可以是简单资源或资源集合
例如,Gmail API 有用户的集合,每个用户有信息的集合、线程的集合、标签的集合、一个资料资源和一些设置项资源。
虽然存储系统和 REST API 之间存在一些概念上的一致性,但是具有面向资源的 API 的服务不一定是数据库,并且在解释资源和方法方面具有巨大的灵活性。例如,创建日历事件(资源)可以为参加会议者创建附加事件,向参加者发送邮件邀请,预约会议室和更新视频会议时间表。
方法
面向资源的 API 的关键特性是它通过对资源执行的方法(功能)来强调资源(数据模型)。一个典型的面向资源的 API 通过少量方法暴露大量资源。这些方法可以是标准方法也可以是自定义方法。对于本指南,标准方法是 List
、Get
、Create
、Update
和 Delete
。
当一个 API 功能自然地映射到一个标准方法时,应该(should) 在API 设计中使用此方法。对于不能自然映射到标准方法的功能,可以(may) 使用自定义方法。自定义方法提供了与传统 RPC API 相同的设计自由度,能够用来实现常见的编程模式,例如数据库事务和数据分析。
例子
下面的部分列出了一些实际的例子,展示了如何将面向资源的 API 设计应用到大规模服务上。
Gmail API
Gmail API 服务实现了 Gmail API 并提供了 Gmail 的大部分功能。它有以下资源模型:
- Gmail API 服务:
gmail.googleapis.com
用户集合:
users/*
。每个用户有以下资源
- 消息集合:
users/*/messages/*
- 线程集合:
users/*/threads/*
- 标签集合:
users/*/labels/*
- 修改历史集合:
users/*/history/*
- 代表用户资料的资源:
users/*/profile
- 代表用户设置项的资源:
users/*/settings
- 消息集合:
Google Cloud Pub/Sub API
pubsub.googleapis.com
服务实现了Google Cloud Pub/Sub API,它定义了下面的资源模型:
- API 服务:
pubsub.googleapis.com
- 话题集合:
projects/*/topics/*
- 订阅集合:
projects/*/subscriptions/*
注意:其他 Pub/Sub API 的实现可能会选择不同的资源名称方案