爲了保證持續和及時的更新,強烈推薦在個人Github上關注該項目,歡迎各位star/fork或者幫助翻譯html
這篇指南介紹描述了 HTTP+JSON API 的一種設計模式,最初摘錄整理自 Heroku 平臺的 API 設計指引 Heroku 平臺 API 指引。git
這篇指南除了詳細介紹現有的 API 外,Heroku 未來新加入的內部 API 也會符合這種設計模式,咱們但願非 Heroku 員工的API設計者也能感興趣。github
咱們的目標是保持一致性,專一業務邏輯同時避免過分設計。咱們一直試圖找出一種良好的、一致的、顯而易見的 API 設計方法,而並非所謂的"最終/理想模式"。json
咱們假設你熟悉基本的 HTTP+JSON API 設計方法,因此本篇指南並不包含全部的 API 設計基礎。設計模式
咱們歡迎你爲這篇指南作貢獻。api
爲每一次的響應返回合適的HTTP狀態碼。 好的響應應該使用以下的狀態碼:服務器
200
: GET
請求成功,及DELETE
或PATCH
同步請求完成,或者PUT
同步更新一個已存在的資源app
201
: POST
同步請求完成,或者PUT
同步建立一個新的資源dom
202
: POST
,PUT
,DELETE
,或PATCH
請求接收,將被異步處理curl
206
: GET
請求成功,可是隻返回一部分,參考:上文中範圍分頁
使用身份認證(authentication)和受權(authorization)錯誤碼時須要注意:
401 Unauthorized
: 用戶未認證,請求失敗
403 Forbidden
: 用戶無權限訪問該資源,請求失敗
當用戶請求錯誤時,提供合適的狀態碼能夠提供額外的信息:
422 Unprocessable Entity
: 請求被服務器正確解析,可是包含無效字段
429 Too Many Requests
: 由於訪問頻繁,你已經被限制訪問,稍後重試
500 Internal Server Error
: 服務器錯誤,確認狀態並報告問題
對於用戶錯誤和服務器錯誤狀況狀態碼,參考: HTTP response code spec
提供所有可顯現的資源 (例如: 這個對象的全部屬性) ,當響應碼爲200或是201時返回全部可用資源,包含 PUT
/PATCH
和 DELETE
請求,例如:
$ curl -X DELETE \ https://service.com/apps/1f9b/domains/0fd4 HTTP/1.1 200 OK Content-Type: application/json;charset=utf-8 ... { "created_at": "2012-01-01T12:00:00Z", "hostname": "subdomain.example.com", "id": "01234567-89ab-cdef-0123-456789abcdef", "updated_at": "2012-01-01T12:00:00Z" }
當請求狀態碼爲202時,不返回全部可用資源,例如:
$ curl -X DELETE \ https://service.com/apps/1f9b/dynos/05bd HTTP/1.1 202 Accepted Content-Type: application/json;charset=utf-8 ... {}
在 PUT
/PATCH
/POST
請求的正文(request bodies)中使用JSON格式數據,而不是使用 form 表單形式的數據。這與咱們使用JSON格式返回請求相對應,例如:
$ curl -X POST https://service.com/apps \ -H "Content-Type: application/json" \ -d '{"name": "demoapp"}' { "id": "01234567-89ab-cdef-0123-456789abcdef", "name": "demoapp", "owner": { "email": "username@example.com", "id": "01234567-89ab-cdef-0123-456789abcdef" }, ... }
使用複數形式爲資源命名,除非這個資源在系統中是單例的 (例如,在大多數系統中,給定的用戶賬戶只有一個)。 這種方式保持了特定資源的統一性。
好的末尾不須要爲資源指定特殊的行爲,但在特殊狀況下,爲某些資源指定行爲倒是必要的。爲了描述清楚,在行爲前加上一個標準的actions
:
/resources/:resource/actions/:action
例如:
/runs/{run_id}/actions/stop
爲了和域名命名規則保持一致,使用小寫字母並用-
分割路徑名字,例如:
service-api.com/users service-api.com/app-setups
屬性也使用小寫字母,可是屬性名要用下劃線_
分割,以便在Javascript中省略引號。 例如:
service_class: "first"
在某些狀況下,讓用戶提供ID去定位資源是不方便的。例如,一個用戶想取得他在Heroku平臺app信息,可是這個app的惟一標識是UUID。這種狀況下,你應該支持接口經過名字和ID都能訪問,例如:
$ curl https://service.com/apps/{app_id_or_name} $ curl https://service.com/apps/97addcf0-c182 $ curl https://service.com/apps/www-prod
不要只接受使用名字而放棄了使用id。
在一些有父路徑/子路徑嵌套關係的資源數據模塊中,路徑可能有很是深的嵌套關係,例如:
/orgs/{org_id}/apps/{app_id}/dynos/{dyno_id}
推薦在根(root)路徑下指定資源來限制路徑的嵌套深度。使用嵌套指定範圍的資源。在上述例子中,dyno屬於app,app屬於org能夠表示爲:
/orgs/{org_id} /orgs/{org_id}/apps /apps/{app_id} /apps/{app_id}/dynos /dynos/{dyno_id}