1. 程式人生 > 程式設計 >RESTful資源命名最佳實踐

RESTful資源命名最佳實踐

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

一個資源可以是單個的也可以是一個集合。比如customers是一個集合,而customer是單個資源。我們可以定義customers這個集合的資源的URI是/customers,而單個customer資源的URI是/customers/{customerId}

資源也可以包含子集合的資源。比如,使用/customers/{customerId}/accounts 來表示某個customer下的account集合資源。同樣的,對於account集合資源下的單個account我們可以定義成這樣:/customers/{customerId}/accounts/{accountId}

REST API使用統一資源識別符號(URI)來定址資源。REST API設計者應該建立URI,將REST API的資源模型傳達給潛在的客戶端開發人員。當資源命名良好時,API直觀且易於使用。如果做得不好,那麼相同的API會感覺難以使用和理解。

使用名詞來表示資源

RESTful URI應該引用作為事物(名詞)的資源而不是引用動作(動詞),因為名詞具有動詞不具有的屬性 - 類似於具有屬性的資源。資源的一些示例是:

  1. 系統的使用者
  2. 使用者賬戶(銀行的場景):
  3. 網路裝置

它們的資源URI可以被設計成下面這樣:

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。

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

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

複製程式碼