编号 | 121 |
---|---|
原文链接 | AIP-121: Resource-oriented design |
状态 | 批准 |
创建日期 | 2019-01-26 |
更新日期 | 2019-01-26 |
面向资源设计是一种用于定义RPC API的模式,基于一下几个高层设计原则(其中大部分是近年公开HTTP API的共同特点):
- API的基本构建块是独立命名的 资源 (名词),以及资源之间的关系和层次结构。
- 少量的标准 方法 (动词)提供了大部分常见操作的语义。当然在标准方法不适用的情况下,可以使用自定义方法。
- 无状态协议:客户端和服务器之间的每次交互都是独立的,客户端和服务器都有明确的职责。
读者可能会注意到这些原则与一些REST原则是相似的;面向资源设计借鉴了REST原则,并在适当的地方定义了自己的模式。
指导
在设计API时,请考虑以下内容(大致按逻辑顺序):
- API将提供的资源(名词)
- 资源之间的关系和层次结构
- 每个资源的模式
- 每个资源提供的方法(动词),尽量使用标准动词。
资源
面向资源的API通常 应该 使用资源层次结构模型,其中每个节点是单一资源或资源集合。
集合 包含 相同类型 的资源。例如出版商拥有其出版的书籍集合。资源通常包含域,也可以包含任意数量的子资源(通常是集合)。
注意: 虽然存储系统和API之间存在一些概念上的相似,但面向资源的API服务不一定是数据库,并且在处理资源和方法方面非常灵活。API设计者 不应 假定API反映数据库模式。实际上,让API接口和底层数据库采用同一模式的方法是一种反模式,将接口与底层系统耦合。
方法
面向资源的API强调资源(数据模型)而非操作资源的方法(功能)。典型的面向资源API发布大量资源,每个资源只支持少量方法。这些方法可以是标准方法(Get、List、Create、Update、Delete),也可以是自定义方法。
如果标准方法(或同一*服务*中的自定义方法)的请求或响应*是*资源或*包含*资源,则该资源在所有方法中的资源模式*必须*相同。
标准方法 | 请求 | 响应 |
---|---|---|
--------------- | --------------------- | ---------------------- |
Create | 包含资源 | 是资源 |
Get | 无 | 是资源 |
Update | 包含资源 | 是资源 |
Delete | 无 | 无 |
List | 无 | 包含资源 |
上表描述了标准方法与资源的关系,其中"无"表示资源既不是,也不包含在请求或响应中。
资源 必须 至少支持Get:客户端必须能够在执行诸如Create、Update或Delete之类的修改操作后验证资源的状态。
除了单例资源(这类资源不存在多个实例),资源也 必须 也支持List,
注意: 在面向资源设计中使用自定义方法 不 意味着要定义新的或自定义HTTP动词。自定义方法使用传统的HTTP动词(通常是
POST
)并在URI中添加自定义动词。
API 应当 优先使用标准方法,而非自定义方法;自定义方法的目的是支持哪些无法明确映射到任何标准方法的功能。自定义方法提供了与传统RPC API同样自由的设计方法,可以实现常见的编程模式,如数据库事务、导入和导出或数据分析。
强一致性
对于在管理平面上操作的方法,这些操作完成时(无论是成功还是失败、后台操作还是同步操作),资源存在性状态和所有用户可以设置的值 必须 达到稳定状态。
仅输出的值中,与资源状态无关的也 应当 达到稳定状态,因为与资源状态相关的值已经是稳定的。
示例包括:
- 在成功CREATE后,若这是资源上的最后修改操作,GET请求 必须 返回该资源。
- 在成功UPDATE后,若这是资源上的最后修改操作,GET请求 必须 返回UPDATE请求的最终值。
- 在成功DELETE后,若这是资源上的最后修改操作,GET请求 必须 返回
NOT_FOUND
(或在使用软删除时返回带有DELETED
状态值的资源)
面向资源API的客户端通常需要按顺序编排多个操作(例如创建资源A,再创建依赖于A的资源B)。操作完成后资源立即反映出稳定的用户状态,这一要求保证了客户端可以安全的将方法完成作为开始下一个操作的信号。
理想情况下,仅输出域也应遵守相同的指导原则。由于这些域通常可以表示资源的实时状态,有时在修改操作成功执行后,需要改变这些值以反映资源状态变化。
无状态协议
与当今大多数公开API一样,面向资源的API 必须 在无状态协议上运行:单一请求的基本行为独立于调用者发出的其他请求。也就是说,每个请求都独立于该客户端或其他客户端发出的其他请求,并且API发布的资源可以直接定位,不需要使用一系列特定请求来"找到"所需的资源。
在无状态协议API中,服务器负责保存数据,数据可以在多个客户端之间共享,客户端负责维护应用程序状态。
循环引用
资源之间的关系(例如资源引用) 必须 可以通过有向无环图表示。上下级关系也 必须 没有环,并且根据AIP-124,每个资源实例只有一个规范的上级资源。
资源之间的循环引用增加了资源管理工作的复杂性。考虑两个相互引用的资源A和B。创建这些资源的过程是:
- 创建A,先不引用B。检索A的标识。
- 创建B,引用A。检索B的标识。
- 更新A,引用B。
删除操作也会更加复杂,因为要判断先取消哪个资源的引用才能删除成功。
这个要求不适用于通过仅输出域表示的关系,因为它们不需要由用户指定其值,因此不会增加资源管理工作的复杂性。
修订记录
- 2024-07-08 :阐明上下级关系的无环性质。
- 2023-08-24 :添加关于方法一致性保证的指导。
- 2023-07-23 :阐明无状态协议定义。
- 2023-01-21 :明确要求标准方法采用统一模式。
- 2022-12-19 :添加要求Get和List的章节。
- 2022-11-02 :添加限制资源引用的章节。
- 2019-08-01 :将示例从"书架"改为"出版商",以提供更好的资源所有权示例。