RESTful資源命名最佳實踐

在Rest中,數據的呈現方式叫作資源(Resource)。擁有強大而一致的REST資源命名策略,是最好的設計決策。mysql

一個資源能夠是單個的也能夠是一個集合。好比customers是一個集合,而customer是單個資源。咱們能夠定義customers這個集合的資源的URI是/customers,而單個customer資源的URI是/customers/{customerId}sql

資源也能夠包含子集合的資源。好比,使用/customers/{customerId}/accounts 來表示某個customer下的account集合資源。一樣的,對於account集合資源下的單個account咱們能夠定義成這樣:/customers/{customerId}/accounts/{accountId}數據庫

REST API使用統一資源標識符(URI)來尋址資源。REST API設計者應該建立URI,將REST API的資源模型傳達給潛在的客戶端開發人員。當資源命名良好時,API直觀且易於使用。若是作得很差,那麼相同的API會感受難以使用和理解。api

使用名詞來表示資源

RESTful URI應該引用做爲事物(名詞)的資源而不是引用動做(動詞),由於名詞具備動詞不具備的屬性 - 相似於具備屬性的資源。資源的一些示例是:瀏覽器

  1. 系統的用戶
  2. 用戶帳戶(銀行的場景):
  3. 網絡設備

它們的資源URI能夠被設計成下面這樣:bash

http://api.example.com/device-management/managed-devices 
http://api.example.com/device-management/managed-devices/{device-id} 
http://api.example.com/user-management/users/
http://api.example.com/user-management/users/{id}

複製代碼

爲了更好的說明咱們把資源原型分爲四個種類(document,collection,store 以及 controller),你應該老是把資源放到其中一個原型中,而且遵照它的統一命名。網絡

document

文檔資源是一種相似於對象實例或數據庫記錄的單一律念(好比mysql中的一行記錄,Mongodb中的document),在REST中,你能夠將其視爲資源集合中的單個資源。文檔的狀態表示一般包括具備值的字段和指向其餘相關資源的連接。函數

使用單數名稱表示文檔資源原型字體

http://api.example.com/device-management/managed-devices/{device-id}
http://api.example.com/user-management/users/{id}
http://api.example.com/user-management/users/admin

複製代碼

collection

集合資源是服務端管理的資源目錄。客戶能夠建議將新資源添加到集合中。可是,要由集合選擇是否建立新資源。集合資源選擇它想要包含的內容,並決定每一個包含的資源的URI。spa

使用複數名稱表示集合資源原型

http://api.example.com/device-management/managed-devices
http://api.example.com/user-management/users
http://api.example.com/user-management/users/{id}/accounts

複製代碼

store

store是客戶端管理的資源庫,store資源容許API客戶端放入資源,取出資源,並決定什麼時候刪除它們。store永遠不會生成新的URI。相反,每一個存儲的資源都有一個客戶端在最初放入存儲時選擇的URI。

使用複數名稱表示store資源原型

http://api.example.com/cart-management/users/{id}/carts
http://api.example.com/song-management/users/{id}/playlists

複製代碼

controller

controller資源有點像程序的概念,controller資源就像可執行函數,帶有參數和返回值;輸入和輸出。

使用動詞表示controller原型

// 查看用戶的信用卡
http://api.example.com/cart-management/users/{id}/cart/checkout

// 播放整個播放列表
http://api.example.com/song-management/users/{id}/playlist/play
複製代碼

這裏的controller爲何要用動詞呢?其實你們能夠想象下Spring中Controller作了什麼事情,它調用了service組合成各個業務邏輯,將數據組合起來以後進行返回.

一致性

使用一致的資源命名約定和URI格式,以最小化和最大可讀性和可維護性。你能夠實現如下設計提示以實現一致性:

使用正斜槓(/)表示層次關係

正斜槓(/)字符用於URI的路徑部分,以指示資源之間的層次關係

http://api.example.com/device-management
http://api.example.com/device-management/managed-devices
http://api.example.com/device-management/managed-devices/{id}
http://api.example.com/device-management/managed-devices/{id}/scripts
http://api.example.com/device-management/managed-devices/{id}/scripts/{id}
複製代碼

不要在URI中使用尾部正斜槓(/)

做爲URI路徑中的最後一個字符,正斜槓(/)不會添加語義值,並可能致使混淆。最好徹底放棄它們

http://api.example.com/device-management/managed-devices/

/*這個版本更好*/
http://api.example.com/device-management/managed-devices

複製代碼

使用連字符( - )來提升URI的可讀性

要使你的URI易於掃描和解釋,請使用連字符( - )字符來提升長路徑段中名稱的可讀性。

// 更好可讀性
http://api.example.com/inventory-management/managed-entities/{id}/install-script-location

// 可讀性不夠高
http://api.example.com/inventory-management/managedEntities/{id}/installScriptLocation
複製代碼

不用使用下滑線 _

可使用下劃線代替連字符做爲分隔符 - 可是根據應用程序的字體,下劃線 _ 字符可能會在某些瀏覽器或屏幕中被部分遮擋或徹底隱藏。爲避免這種混淆,請使用連字符 - 而不是下劃線 _。

// 更具可讀性
http://api.example.com/inventory-management/managed-entities/{id}/install-script-location

// 更容易出錯
http://api.example.com/inventory_management/managed_entities/{id}/install_script_location

複製代碼

在URI中使用小寫字母

方便時,URI路徑中應始終首選小寫字母。

RFC 3986將URI定義爲區分大小寫,但協議和host除外

// 1
http://api.example.org/my-folder/my-doc
// 2
HTTP://API.EXAMPLE.ORG/my-folder/my-doc
// 3
http://api.example.org/My-Folder/my-doc
複製代碼

在上面的例子中,1和2是相同的,但3不是,由於它使用大寫字母的My-Folder。

不要使用文件擴展名

文件擴展名看起來很糟糕,不會增長任何優點。刪除它們也會減小URI的長度。沒理由保留它們。除了上述緣由,若是你想使用文件擴展突出顯示API的媒體類型,那麼你應該依賴於經過Content-Type標頭傳達的媒體類型來肯定如何處理正文的內容。

// 不要這樣用
http://api.example.com/device-management/managed-devices.xml

// 正確的URI
http://api.example.com/device-management/managed-devices

複製代碼

切勿在URI中使用CRUD函數名稱

URI不該用於指示執行CRUD功能。URI應該用於惟一標識資源,而不是對它們的任何操做。應使用HTTP請求方法來指示執行哪一個CRUD功能。

// 獲取全部設備
HTTP GET http://api.example.com/device-management/managed-devices
// 建立新設備
HTTP POST http://api.example.com/device-management/managed-devices

// 根據給定id獲取設備
HTTP GET http://api.example.com/device-management/managed-devices/{id}

// 根據給定id更新設備
HTTP PUT http://api.example.com/device-management/managed-devices/{id}

// 根據給定id刪除設備
HTTP DELETE http://api.example.com/device-management/managed-devices/{id}

複製代碼

使用查詢組件過濾URI集合

不少時候,你會遇到須要根據某些特定資源屬性對須要排序,過濾或限制的資源集合的要求。爲此,不要建立新的API - 而是在資源集合API中啓用排序,過濾和分頁功能,並將輸入參數做爲查詢參數傳遞

http://api.example.com/device-management/managed-devices
http://api.example.com/device-management/managed-devices?region=USA
http://api.example.com/device-management/managed-devices?region=USA&brand=XYZ
http://api.example.com/device-management/managed-devices?region=USA&brand=XYZ&sort=installation-date

複製代碼
相關文章
相關標籤/搜索