簡體   English   中英

對於樹層次結構,REST URL架構應該如何?

[英]How should a REST URL schema look like for a tree hierarchy?

我們假設我有商店,商店貨架和貨架上的產品。 因此,為了獲得商店貨架上的產品列表,我將使用以下請求:

GET http://server/stores/123/shelves/456/products

從這里,我如何獲得個別產品? 我應該使用:

GET http://server/products/789

要么:

GET http://server/stores/123/shelves/456/products/789

第一種方法更簡潔,因為一旦獲得產品列表,如果您只想查看特定產品的詳細信息,則不關心它屬於哪個商店。 但是,第二種方法更符合邏輯,因為您正在查看特定商店中特定貨架的產品。

同樣,PUT / DELETE操作怎么樣?

DELETE http://server/stores/123/shelves/456/products/789

要么:

DELETE http://server/products/789

為這樣的樹層次結構設計模式的正確方法是什么?

PS如果我誤解了有關REST架構的一些內容,請提供有關如何使其更好的示例。 有太多人喜歡說“REST不是CRUD”和“REST不是RPC”,然后絕對沒有提供良好RESTful設計的澄清或示例。

我已經注意到RESTful URI設計的兩種方法: 分層和過濾

我認為層次結構過於冗長,有可能存在冗余端點(而不是DRY),並且偽裝成您真正感興趣的資源狀態(畢竟,REST = 代表性狀態轉移)。

我贊成簡單的URI

簡單優雅。 我會選擇像這樣的URI結構

GET http://server/products/789

因為我對產品資源的狀態感興趣。

如果我想要所有屬於特定商店特定貨架的產品,那么我會這樣做

GET http://server/products?store=123&shelf=456

如果我想在特定貨架上的特定商店創建產品,那么我會發布

{
    product: {
        store: 123,
        shelf: 456,
        name: "test product"
    }
}

通過

POST http://server/products

最終,它是tomayto,tomahto

REST不需要一個在另一個上。 但是,根據我自己的經驗,使用將單個實體映射到單個端點的RESTful API(例如:iOS上的RestKit對象映射)而不是根據傳遞的參數將實體映射到許多不同的端點更有效。

關於REST

就REST而言,它不是協議,也沒有RFC。 它與HTTP / 1.1 RFC緊密相關,作為實現其CRUD操作的一種方式,但許多軟件工程師會認為REST不依賴於HTTP。 我不同意並考慮諸如猜想,因為UCI的Roy Fielding的原始論文( http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm )解釋了REST和HTTP /的深層次連接1.1。 您也可以享受Roy對該主題的看法: http//roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

REST定義的原則可以應用於其他協議,但REST是為互聯網構建的,而HTTP是萬維網協議。

REST與RPC

RPC就是要調用遠程函數,而且是以動詞為中心的

REST就是使用CRUD約定來處理數據,具體取決於CRUD操作如何應用於給定的數據類型並且是以名詞為中心的

您可以使用REST或RPC完成相同的操作,但REST遵循DRY原則,因為對於每個URI,您可以執行4個操作,而RPC需要每個操作的端點。

PS

這很大程度上是我的看法,並且基於我的經驗,但我希望它能說明如何最有效地設計RESTful URI模式。 與往常一樣,您的具體目標和需求將影響您的選擇,但簡單性始終是目標的良好目標。

創建產品應該只是一個POST

http://server/product

更新產品應該只是一個PUT

http://server/product/$id

獲得產品應該只是一個GET

http://server/product/$id

刪除產品應該只是一個刪除

http://server/product/$id

您應該使用那里的http方法從更簡單的uri結構中獲取更多功能。 如果創建產品需要傳遞商店和貨架作為要求,那么這些應該在POST的主體中傳遞(或者如果您要更換貨架,則傳遞PUT)。

當有人對http://server/product/$id進行GET時,他們會得到某種xml / json響應,對吧? 那是什么樣的? 創建或更新的傳入數據應在請求正文中以相同的方式進行POST或PUT。 這就是你如何通過商店和貨架,而不是通過uri。 uri應該盡可能簡單,只需指向資源(產品),使用http動詞來區分功能。

如果你想獲得貨架23的內容,你可以去GET

http://server/shelf/23

當您這樣做時,您將獲得一個json / xml / custom媒體類型文檔,其中包含貨架數據和一組產品元素,其中包含返回其產品uri的鏈接。

如果您希望能夠將產品23從一個架子移動到另一個架子,那么您需要進行PUT操作

http://server/product/23 

在PUT的主體中,您可以選擇代表您的產品,但使用更新的貨架。

一開始這是一種奇怪的思維模式,因為你不是在處理整個系統的功能,而是專注於資源(產品,貨架,商店)並使用http動詞將它們暴露給宇宙。

由於產品可能在幾個商店或幾個貨架(類別?),我會讓每個產品都有一個唯一的數字,無論它在層次結構中的位置如何。 然后使用扁平產品編號。 這使得API在您的商店中移動某些產品時更加穩定。

簡而言之,不要在API中添加不必要的冗余。 要獲得貨架清單商店ID就足夠了,對於產品清單,貨架ID就夠了......等等。

不要基於URL結構設計REST api。 以下是我認為您應該如何設計REST API。

嘗試定義REST接口而不討論哪些鏈接將包含在哪些資源中,就像討論RPC接口並忽略參數和返回值一樣。

看起來你正在嘗試構建許多不同的用例,但所有內容都被構建到一個超級服務中。 打破它會更好。

http://server/product_info/123123 or http://server/product_info?product=123123
http://server/product_inventory?store=123&shelf=345

那么你也可以支持:

http://server/product_inventory?store=123

然后PUT和DELETE對於更改庫存或添加新產品有意義。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM