方法 | 操做 | 場景html |
GET | 讀 | /cars /cars/711 |
POST | 建立 | /cars |
PUT | 修改 | /cars/711 /cars |
PATCH | 部分修改 | /cars/711 |
DELETE | 刪除 | /cars/711 |
GET /tickets - 獲取 tickets 列表
GET /tickets/12 - 獲取一個單獨的 ticket
POST /tickets - 建立一個新的 ticket
PUT /tickets/12 - 更新 ticket #12
PATCH /tickets/12 - 部分更新 ticket #12
DELETE /tickets/12 - 刪除 ticket #12api
不要使用GET 進行狀態改變,瀏覽器
GET /users/711?activate
GET /users/711/activate
若是一個資源與另一個資源有關係,使用子資源:緩存
GET /tickets/12/messages - 獲取ticket #12下的消息列表 GET /tickets/12/messages/5 - 獲取ticket #12下的編號爲5的消息 POST /tickets/12/messages - 爲ticket #12建立一個新消息 PUT /tickets/12/messages/5 - 更新ticket #12下的編號爲5的消息 PATCH /tickets/12/messages/5 - 部分更新ticket #12下的編號爲5的消息 DELETE /tickets/12/messages/5 - 刪除ticket #12下的編號爲5的消息
在客戶端和服務端,雙方都要知道通信的格式,格式在HTTP-Header中指定服務器
Content-Type 定義請求格式
Accept 定義系列可接受的響應格式restful
最好是儘可能保持基本資源URL的簡潔性。 複雜結果過濾器、排序需求和高級搜索 (當限定在單一類型的資源時) ,都可以做爲在基本URL之上的查詢參數來輕鬆實現。下面讓咱們更詳細的看一下:網絡
1)過濾: 對每個字段使用一個惟一查詢參數,就能夠實現過濾。 例如,當經過「/tickets」終端來請求一個票據列表時,你可能想要限定只要那些在售的票。這能夠經過一個像app
GET /tickets?state=open
這樣的請求來實現。這裏「state」是一個實現了過濾功能的查詢參數。負載均衡
2)排序: 跟過濾相似, 一個泛型參數排序能夠被用來描述排序的規則. 爲適應複雜排序需求,讓排序參數採起逗號分隔的字段列表的形式,每個字段前均可能有一個負號來表示按降序排序。咱們看幾個例子:搜索引擎
GET /tickets?sort=-priority - 獲取票據列表,按優先級字段降序排序 GET /tickets?sort=-priority,created_at - 獲取票據列表,按「priority」字段降序排序。在一個特定的優先級內,較早的票排在前面
3)搜索: 有時基本的過濾不能知足需求,這時你就須要全文檢索的力量。或許你已經在使用 ElasticSearch 或者其它基於 Lucene 的搜索技術。當全文檢索被用做獲取某種特定資源的資源實例的機制時, 它能夠被暴露在API中,做爲資源終端的查詢參數,咱們叫它「q」。搜索類查詢應當被直接交給搜索引擎,而且API的產出物應當具備一樣的格式,以一個普通列表做爲結果。
把這些組合在一塊兒,咱們能夠建立如下一些查詢:
GET /tickets?sort=-updated_at - 獲取最近更新的票 GET /tickets?state=closed&sort=-updated_at - 獲取最近更新而且狀態爲關閉的票。 GET /tickets?q=return&state=open&sort=-priority,created_at - 獲取優先級最高、最早建立的、狀態爲開放的票,而且票上有 'return' 字樣。
4)通常查詢定義方式
爲了使普通用戶的API使用體驗更加愉快, 考慮把條件集合包裝進容易訪問的RESTful 路徑中。好比上面的,最近關閉的票的查詢能夠被包裝成
GET /tickets/recently_closed
5)限制查詢返回字段
API的使用者並不老是須要一個資源的完整表示。選擇返回字段的功能由來已久,它使得API使用者可以最小化網絡阻塞,並加速他們對API的調用。
使用一個字段查詢參數,它包含一個用逗號隔開的字段列表。例如,下列請求得到的信息將剛剛足夠展現一個在售票的有序列表:
GET /tickets?fields=id,subject,customer_name,updated_at&state=open&sort=-updated_at
6)Paging分頁
使用 limit 和offset.實現分頁,缺省limit=20 和offset=0;
GET /cars?offset=10&limit=5
爲了將總數發給客戶端,使用訂製的HTTP頭: X-Total-Count.
連接到下一頁或上一頁能夠在HTTP頭的link規定,遵循Link規定:
Link: <https://blog.mwaysolutions.com/sample/api/v1/cars?offset=15&limit=5>; rel="next", <https://blog.mwaysolutions.com/sample/api/v1/cars?offset=50&limit=3>; rel="last", <https://blog.mwaysolutions.com/sample/api/v1/cars?offset=0&limit=5>; rel="first", <https://blog.mwaysolutions.com/sample/api/v1/cars?offset=5&limit=5>; rel="prev",
一個 PUT, POST 或者 PATCH 調用可能會對指定資源的某些字段形成更改,而這些字段本不在提供的參數之列 (例如: created_at 或 updated_at 這兩個時間戳)。 爲了防止API使用者爲了獲取更新後的資源而再次調用該API,應當使API把更新(或建立)後的資源做爲response的一部分來返回。
以一個產生建立活動的 POST 操做爲例, 使用一個 HTTP 201 狀態代碼 而後包含一個 Location header 來指向新生資源的URL。
選定一種方式:snake_case vs camelCase
一個提供空白符壓縮輸出的API,從瀏覽器中查看結果並不美觀。雖然一些有序的查詢參數(如 ?pretty=true )能夠提供來使漂亮打印生效,一個默認狀況下能進行漂亮打印的API更爲平易近人。額外數據傳輸的成本是微不足道的,尤爲是當你比較不執行gzip壓縮的成本。
考慮一些用例:假設分析一個API消費者正在調試而且有本身的代碼來打印出從API收到的數據——默認狀況下這應是可讀的。或者,若是消費者抓住他們的代碼生成的URL,並直接從瀏覽器訪問它——默認狀況下這應是可讀的。這些都是小事情。作好小事情會使一個API能被更愉快地使用
就像一個HTML錯誤頁面給訪問者展現了有用的錯誤信息同樣,一個API應當以一種已知的可以使用的格式來提供有用的錯誤信息。 錯誤的表示形式應當和其它任何資源沒有區別,只是有一套本身的字段。
API應當老是返回有意義的HTTP狀態代碼。API錯誤一般被分紅兩種類型: 表明客戶端問題的400系列狀態碼和表明服務器問題的500系列狀態碼。最簡狀況下,API應當把便於使用的JSON格式做爲400系列錯誤的標準化表示。若是可能(意思是,若是負載均衡和反向代理能建立自定義的錯誤實體), 這也適用於500系列錯誤代碼。
一個JSON格式的錯誤信息體應當爲開發者提供幾樣東西 - 一個有用的錯誤信息,一個惟一的錯誤代碼 (可以用來在文檔中查詢詳細的錯誤信息) 和可能的詳細描述。這樣一個JSON格式的輸出可能會像下面這樣:
{ "code" : 1234, "message" : "Something bad happened :(", "description" : "More details about the error here" }
對PUT, PATCH和POST請求進行錯誤驗證將須要一個字段分解。下面多是最好的模式:使用一個固定的頂層錯誤代碼來驗證錯誤,並在額外的字段中提供詳細錯誤信息,就像這樣:
{ "code" : 1024, "message" : "Validation Failed", "errors" : [ { "code" : 5432, "field" : "first_name", "message" : "First name cannot have fancy characters" }, { "code" : 5622, "field" : "password", "message" : "Password cannot be blank" } ] }
HTTP定義了一套能夠從API返回的有意義的狀態代碼。 這些代碼可以用來幫助API使用者對不一樣的響應作出相應處理。我已經把你必然會用到的那些列成了一個簡短的清單:
----------------------------------------------------------------------
參考資料:
一、《Best Practices for Designing a Pragmatic RESTful API》
二、《RESTful API 設計最佳實踐》(對上文的譯文)
三、《Principles of good RESTful API Design》