在REST中,主資料表示稱為資源。擁有強大而一緻的REST資源命名政策 - 肯定會證明您是長期最好的設計決策之一。
REST中資訊的關鍵抽象是一種資源。可以命名的任何資訊都可以是資源:文檔或圖像,臨時服務(例如“洛杉矶的今天天氣”),其他資源的集合,非虛拟對象(例如人)等等。換句話說,任何可能是作者超文本引用目标的概念都必須符合資源的定義。資源是到一組實體的概念映射,而不是與任何特定時間點的映射相對應的實體。羅伊菲爾丁的論文
一個資源可以是一個單或集合。例如,“ customers”是集合資源,“ customer”是單例資源(在銀行業務域中)。我們可以customers使用URI“ /customers” 來識别“ ”集合資源。我們可以customer使用URI“ /customers/{customerId}” 識别單個“ ”資源。
一個資源可能包含子集的資源也。例如,可以使用URN“ ”(在銀行業務域中)識别accounts特定“ customer”的子集合資源“ ” /customers/{customerId}/accounts。類似地,account子集合資源“ ”内的單個資源“ ” accounts可以如下辨別:“ /customers/{customerId}/accounts/{accountId}”。
REST API使用統一資源辨別符(URI)來尋址資源。REST API設計者應該建立URI,将REST API的資源模型傳達給潛在的用戶端開發人員。當資源命名良好時,API直覺且易于使用。如果做得不好,那麼相同的API會感覺難以使用和了解。
統一接口的限制部分通過URI和HTTP動詞的組合來解決,并且根據标準和約定使用它們。
以下是為新API建立資源URI時可以使用的一些提示。
REST資源命名最佳實踐
使用名詞來表示資源
RESTful URI應該引用作為事物(名詞)的資源而不是引用動作(動詞),因為名詞具有動詞不具有的屬性 - 類似于具有屬性的資源。資源的一些示例是:
系統的使用者
使用者帳戶
網絡裝置等
他們的資源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
文檔資源是一種類似于對象執行個體或資料庫記錄的單一概念。在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
商店是用戶端管理的資源庫。商店資源允許API用戶端放入資源,将其退出,并決定何時删除它們。商店永遠不會生成新的URI。相反,每個存儲的資源都有一個用戶端在最初放入存儲時選擇的URI。
使用“複數”名稱表示商店資源原型。
http://api.example.com/cart-management/users/{id}/carts http://api.example.com/song-management/users/{id}/playlists
controller
控制器資源模拟程式概念。控制器資源就像可執行函數,帶有參數和傳回值; 輸入和輸出。
使用“動詞”表示控制器原型。
http://api.example.com/cart-management/users/{id}/cart/checkout http://api.example.com/song-management/users/{id}/playlist/play
一緻性是關鍵
使用一緻的資源命名約定和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 /This is much better version/
使用連字元( - )來提高URI的可讀性
要使您的URI易于掃描和解釋,請使用連字元( - )字元來提高長路徑段中名稱的可讀性。
http://api.example.com/inventory-management/managed-entities/{id}/install-script-location //More readable
http://api.example.com/inventory-management/managedEntities/{id}/installScriptLocation //Less readable
不要使用下劃線(_)
可以使用下劃線代替連字元作為分隔符 - 但是根據應用程式的字型,下劃線(_)字元可能會在某些浏覽器或螢幕中被部分遮擋或完全隐藏。
為避免這種混淆,請使用連字元( - )而不是下劃線(_)。
http://api.example.com/inventory-management/managed-entities/{id}/install-script-location //More readable
http://api.example.com/inventory_management/managed_entities/{id}/install_script_location //More error prone
在URI中使用小寫字母
友善時,URI路徑中應始終首選小寫字母。
RFC 3986将URI定義為區分大小寫,但方案和主機元件除外。例如
http://api.example.org/my-folder/my-doc //1
HTTP://API.EXAMPLE.ORG/my-folder/my-doc //2
http://api.example.org/My-Folder/my-doc //3
在上面的例子中,1和2是相同的,但3不是因為它使用大寫字母的My-Folder。
不要使用檔案擴充名
檔案擴充名看起來很糟糕,不會增加任何優勢。删除它們也會減少URI的長度。沒理由保留它們。
除了上述原因,如果您想使用檔案擴充突出顯示API的媒體類型,那麼您應該依賴于通過Content-Type标題傳達的媒體類型來确定如何處理正文的内容。
http://api.example.com/device-management/managed-devices.xml /Do not use it/
http://api.example.com/device-management/managed-devices /This is correct URI/
切勿在URI中使用CRUD函數名稱
URI不應用于訓示執行CRUD功能。URI應該用于唯一辨別資源,而不是對它們的任何操作。應使用HTTP請求方法來訓示執行哪個CRUD功能。
HTTP GET http://api.example.com/device-management/managed-devices //Get all devices
HTTP POST http://api.example.com/device-management/managed-devices //Create new Device
HTTP GET http://api.example.com/device-management/managed-devices/{id} //Get device for given Id
HTTP PUT http://api.example.com/device-management/managed-devices/{id} //Update device for given Id
HTTP DELETE http://api.example.com/device-management/managed-devices/{id} //Delete device for given Id