面向資源的設計
這份設計指南的目標是幫助開發人員設計簡單、一致、易用的網絡API。同時,它也有助於收斂基於socket的API和(注:原文是with,這里翻譯為“和”)基於HTTP的REST API。
以前,人們根據諸如CORBA和Windows COM這樣的API接口和方法設計RPC API。隨着時間的推移,接口和方法越來越多。最后,接口和方法數不勝數又各不相同。開發人員要正確使用它們,必須仔細了解每一個的用法,這很浪費時間而且容易出錯。
2000年,為了與HTTP1.1搭配使用,REST架構風格出現。它的核心原則是定義用少量方法就能操作的命名資源。資源和方法可視為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設計上,本指南應用面向資源設計的原則,定義了眾多常見的設計模式以提高易用性並降低復雜性。
注意:本設計指南解釋了如何將REST原則用於獨立於編程語言,操作系統或者網絡協議的API設計,它不只是用於創建REST API的指南。
什么是REST API
一組REST API被建模為一組可獨立尋址的資源(API的名詞)。資源被通過資源名稱被引用,通過一小組方法(也被稱為動詞或者操作)被操作。
Google REST API(也被稱為REST方法)的標准方法有List
,Get
,Create
,Update
和Delete
。API的設計者也可以用自定義方法(也被稱為自定義動詞或者自定義操作),來完成那些不易對應到標准方法的功能,比如數據庫事務。
注意:自定義動詞不意味着創建自定義的HTTP動詞以支持自定義方法。對於基於HTTP的API來說,自定義動詞被對應到最合適的HTTP動詞上。(譯者注:不能自創HTTP動詞,應該使用含義最接近的HTTP動詞去設計API)
設計流程
設計指南建議使用以下步驟設計面向資源的API(更多細節請參考下面指定章節):
- 確定一個API提供什么類型的資源
- 確定資源之間的關系
- 根據資源類型和關系確定資源命名方案
- 明確資源schema
- 給資源添加最少的方法集
資源
面向資源的API通常被建模為一個資源層次結構。其中每一個節點可以是一個簡單資源也可以是一組資源。為了方便,它們通常被稱為資源或者資源組。
- 資源組包含相同類型的一系列資源。比如,一個用戶有一組聯系人。
- 資源有相同的狀態,也有零或者多個子資源。每一個子資源可以是單個資源也可是一組資源。
例如,Gmail API有一組用戶,每個用戶有一組消息,一組主題,一組標簽,單個用戶配置資源或多個設置項資源。
盡管REST API和存儲系統有概念上的一致性,但具有面向資源的API的服務不一定是數據庫,並且在如何解釋資源和方法上有巨大的靈活性。比如,創建一個日歷事件(資源)可能會為參會者創建附加事件,向參會者發送邀請郵件,預約會議室,更新視頻會議日程表。
方法
面向資源的API的關鍵特性是強調資源(數據模型)和(譯者注:原文看起來是筆誤,這里應該翻譯為和)運行在資源上的方法(功能)。典型的面向資源的API通過少量方法的暴露大量資源。這些方法可以是標准的或者自定義的。在本指南中,標准方法是指:List
,Get
,Create
,Update
和Delete
。
當API功能自然地映射到一個標准方法時,這個方法應當用於API設計。若當功能不能自然的映射到標准方法時,可以使用自定義方法。自定義方法能提供與傳統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
服務實現了Goole Cloud Pub/Sub API,它定義了以下資源模型:
- API服務:
pubsub.googleapis.com
- 一組主題:
projects/*/topics/*
。 - 一組訂閱:
projects/*/subscriptions/*
。
注意:PUB/SUB API的其他實現可能選用了與上面不同的命名規則。