白宮Web API的指南和示例
本文件提供了白宮Web API的指南和示例,鼓勵跨前後端的一致性,可維護性和最佳實踐。白宮API旨在平衡真正的RESTful API介面和積極的開發者體驗(DX)。該檔案大量借鑑:
- ofollow,noindex" target="_blank">設計HTTP介面和RESTful Web服務
- API Facade Pattern ,作者:Brian Mulloy,Apigee
- Web API設計 ,作者:Brian Mulloy,Apigee
- 菲爾丁關於REST的論文
這些指南旨在支援真正的RESTful API。以下是一些例外情況:
- 將API的版本號放在URL中(參見下面的示例)。不接受任何未指定版本號的請求。
-
允許使用者像這樣請求JSON或XML等格式:
- [url]http://example.gov/api/v1/magazines.json[/url]
- [url]http://example.gov/api/v1/magazines.xml[/url]
RESTful URL的一般準則
- URL標識資源。
- 網址應包含名詞,而不是動詞。
- 使用複數名詞只是為了一致性(沒有單數名詞)。
- 使用HTTP謂詞(GET,POST,PUT,DELETE)對集合和元素進行操作。
- 不應該比資源/識別符號/資源更深嵌套了。
- 將版本號放在URL的尾部,例如[url]http://example.com/v1/path/to/resource[/url]。
-
URL 和Header的選擇:
- 如果更改了你編寫的邏輯以處理響應,請將其放入URL中。
- 如果它沒有更改每個響應的邏輯,例如OAuth資訊,請將其放在標題Header中。
- 在逗號分隔列表中指定可選欄位。
- 格式應採用api/v2/resource/{id} .json的形式
好的URL示例
-
雜誌資源列表:
- GET [url]http://www.example.gov/api/v1/magazines.json[/url]
- 過濾是一種查詢:
-
JSON格式的一個雜誌資源:
- GET [url]http://www.example.gov/api/v1/magazines/1234.json[/url]
-
本雜誌中的所有文章(或屬於本雜誌):
- GET [url]http://www.example.gov/api/v1/magazines/1234/articles.json[/url]
-
本雜誌中的所有文章都是XML格式:
- GET [url]http://example.gov/api/v1/magazines/1234/articles.xml[/url]
-
在逗號分隔列表中指定可選欄位:
- GET [url]http://www.example.gov/api/v1/magazines/1234.json?fields=title,subtitle,date[/url]
-
在特定雜誌中新增新文章:
- POST [url]http://example.gov/api/v1/magazines/1234/articles[/url]
錯誤的URL示例
-
非複數名詞:
- [url]http://www.example.gov/magazine[/url]
- [url]http://www.example.gov/magazine/1234[/url]
- [url]http://www.example.gov/publisher/magazine/1234[/url]
-
網址中的動詞:
- [url]http://www.example.gov/magazine/1234/create[/url]
-
在查詢字串之外過濾
- [url]http://www.example.gov/magazines/2011/desc[/url]
HTTP動詞
應使用HTTP謂詞或方法,以符合HTTP / 1.1 標準下的定義。動作時與正在處理的媒體型別及其當前狀態有關。以下是HTTP謂詞如何對映到特定上下文中的建立,讀取,更新,刪除操作的示例:
/dogs
POST: 建立一個狗
GET: 列表
UPDATE:更新
DELETE:刪除所有
響應
- key中不能有值
- 不能有內部特定的名稱(例如“node”和“taxonomy term分類術語”)
- 元資料應僅包含響應集的直接屬性,而不包含響應整合員的屬性
"鍵中沒有值"的好例子
"tags": [
{"id": "125", "name": "Environment"},
{"id": "834", "name": "Water Quality"}
],
"鍵中有值"的壞例子
"tags": [
{"125": "Environment"},
{"834": "Water Quality"}
],
錯誤處理
錯誤響應應包括常見的:HTTP狀態程式碼,開發人員的訊息,終端使用者的訊息(適當時),內部錯誤程式碼(對應於某些特定的內部確定的ID),開發人員可以找到更多資訊的連結。
例如:
{
"status" : 400,
"developerMessage" : "Verbose, plain language description of the problem. Provide developers
suggestions about how to solve their problems here",
"userMessage" : "This is a message that can be passed along to end-users, if needed.",
"errorCode" : "444444",
"moreInfo" : "http://www.example.gov/developer/path/to/help/for/444444,
http://drupal.org/node/444444",
}
使用三個簡單的常見響應程式碼表示(1)成功,(2)由於客戶端問題導致的故障,(3)由於伺服器端問題導致的故障:
[list]
[*]200 - 好的
[*]400 - 錯誤請求
[*]500內部伺服器錯誤
[/list]
版本
[list]
[*]永遠不要在沒有版本號的情況下發布API。
[*]版本應為整數,而不是十進位制數,字首為“v”。例如:
[list]
[*]好:v1,v2,v3
[*]差:v-1.1,v1.2,1.3
[/list]
[*]維護至少一個版本的API。
[/list]
記錄限制
[list]
[*]如果未指定限制,則返回預設限制。
[*]要獲得記錄51到75,請執行以下操作:
[list]
[*]http://example.gov/magazines?limit=25&offset=50
[*]offset = 50表示'跳過前50條記錄'
[*]limit = 25表示'最多返回25條記錄'
[/list]
[/list]
有關記錄限制和總可用計數的資訊也應包含在響應中。例:
{
"metadata": {
"resultset": {
"count": 227,
"offset": 25,
"limit": 25
}
},
"results": []
}
請求和響應示例
API資源
[list]
[*]POST /magazines/[id]/articles
[*]
[/list]
GET /magazines
Example: [url]http://example.gov/api/v1/magazines.json[/url]
響應體:
{
"metadata": {
"resultset": {
"count": 123,
"offset": 0,
"limit": 10
}
},
"results": [
{
"id": "1234",
"type": "magazine",
"title": "Public Water Systems",
"tags": [
{"id": "125", "name": "Environment"},
{"id": "834", "name": "Water Quality"}
],
"created": "1231621302"
},
{
"id": 2351,
"type": "magazine",
"title": "Public Schools",
"tags": [
{"id": "125", "name": "Elementary"},
{"id": "834", "name": "Charter Schools"}
],
"created": "126251302"
}
{
"id": 2351,
"type": "magazine",
"title": "Public Schools",
"tags": [
{"id": "125", "name": "Pre-school"},
],
"created": "126251302"
}
]
}
GET /magazines/[id]
Example: http://example.gov/api/v1/magazines/[id].json
響應體:
{
"id": "1234",
"type": "magazine",
"title": "Public Water Systems",
"tags": [
{"id": "125", "name": "Environment"},
{"id": "834", "name": "Water Quality"}
],
"created": "1231621302"
}
POST /magazines/[id]/articlesExample: Create – POST http://example.gov/api/v1/magazines/[id]/articles 響應體:
[
{
"title": "Raising Revenue",
"author_first_name": "Jane",
"author_last_name": "Smith",
"author_email": "[email protected]",
"year": "2012",
"month": "August",
"day": "18",
"text": "xxxxxxx.. "
}
]
模擬響應
建議每個資源在測試伺服器上接受'mock'引數。傳遞此引數應返回模擬資料響應(繞過後端)
。在開發早期實現此功能可確保API表現出一致的行為,支援測試驅動的開發方法。注意:如果mock引數包含在對生產環境的請求中,則應引發錯誤。
解釋JSONP最簡單是用一個例子。這是StackOverflow中 的定義:
假設您在域名abc.com上,並且您想向域xyz.com發出請求。要做到這一點,你需要跨越域邊界,在大多數瀏覽器領域都是禁忌。繞過此限制的一個專案是標籤。
當您使用這個指令碼標籤時,跨域限制將被忽略,但在正常情況下,您無法對結果做任何事情,只會對指令碼進行評估。
當你向啟用了JSONP的伺服器發出請求時,你會傳遞一個特殊引數,告訴伺服器一些關於您的頁面的資訊。這樣,伺服器就能夠以您的頁面可以處理的方式很好地包裝其響應。例如,假設伺服器需要一個名為“callback”的引數來啟用其JSONP功能。然後你的請求看起來像:
http://www.xyz.com/sample.aspx?callback=mycallback
如果沒有JSONP,這可能會返回一些基本的javascript物件,如下所示:
{ foo: 'bar' }
但是,使用JSONP時,當伺服器收到“callback”引數時,它會以不同的方式包裝結果,返回如下內容:
mycallback({ foo: 'bar' });
如您所見,它現在將呼叫您指定的方法。因此,在您的頁面中,您定義了回撥函式:
mycallback = function(data){ alert(data.foo); };