HTTP API 設計指南(請求部分)

爲了保證持續和及時的更新,強烈推薦在個人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請求成功,及DELETEPATCH同步請求完成,或者PUT同步更新一個已存在的資源app

  • 201: POST 同步請求完成,或者PUT同步建立一個新的資源dom

  • 202: POSTPUTDELETE,或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/PATCHDELETE
請求,例如:

$ 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
...
{}

在請求的body體使用JSON格式數據

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"
  },
  ...
}

使用統一的資源路徑格式

資源名(Resource names)

使用複數形式爲資源命名,除非這個資源在系統中是單例的 (例如,在大多數系統中,給定的用戶賬戶只有一個)。 這種方式保持了特定資源的統一性。

行爲(Actions)

好的末尾不須要爲資源指定特殊的行爲,但在特殊狀況下,爲某些資源指定行爲倒是必要的。爲了描述清楚,在行爲前加上一個標準的actions

/resources/:resource/actions/:action

例如:

/runs/{run_id}/actions/stop

路徑和屬性要小寫

爲了和域名命名規則保持一致,使用小寫字母並用-分割路徑名字,例如:

service-api.com/users
service-api.com/app-setups

屬性也使用小寫字母,可是屬性名要用下劃線_分割,以便在Javascript中省略引號。 例如:

service_class: "first"

支持方便的無id間接引用

在某些狀況下,讓用戶提供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}
相關文章
相關標籤/搜索