2010-07-14 79 views
11

據說在一個定義良好的RESTful系統中,客戶端只需要知道根URI或幾個衆所周知的URI,並且客戶端應該通過這些初始URI發現所有其他的鏈接。我明白這個方法的好處(解耦客戶端),但對我的缺點是,客戶端需要發現鏈接的每個嘗試訪問的東西,即給定資源的層次結構如下時間:連通性和HATEOAS

/collection1 
collection1 
    |-sub1 
    |-sub1sub1 
|-sub1sub1sub1 
     |-sub1sub1sub1sub1 
    |-sub1sub2 
    |-sub2 
    |-sub2sub1 
    |-sub2sub2 
    |-sub3 
    |-sub3sub1 
    |-sub3sub2 

如果我們按照「客戶端只需要知道根URI」的方法,那麼客戶端應該只知道上面的根URI(即/ collection1),其餘的URI應該由客戶端通過超媒體鏈接來發現。我覺得這很麻煩,因爲每次客戶端需要做一個GET時,比如在sub1sub1sub1sub1上,如果客戶端首先在/ collection1上執行GET,並在返回的表示中定義後續鏈接,然後在子資源上執行多個GET以達到期望的資源?還是我對連通性的理解完全錯誤?

最好的問候, 蘇雷什

+0

只是REST服務是無狀態的,客戶端不是。因此,客戶可以記住以前的資源,它們的URL等等,例如通過嵌套的導航菜單... – inf3rno 2013-11-15 04:04:19

回答

6

當您嘗試構建與使用API​​的用戶代理的流不匹配的REST API時,您將遇到此不匹配問題。

考慮當您運行客戶端應用程序時,用戶始終會顯示一些初始屏幕。如果您將此屏幕上的內容和選項與根表示相匹配,則可用鏈接和所需轉換將很好地匹配。當用戶選擇屏幕上的選項時,您可以轉換到其他表示,並且應該更新客戶端UI以反映新的表示。

如果您試圖將REST API建模爲某種鏈接的數據存儲庫和您的客戶端UI作爲獨立的轉換集,那麼您會發現HATEOAS非常痛苦。

+0

痛苦並不一定是真實的:我只有這樣,項目集合的層次結構,以及客戶端在開始時,鑽取一個或兩個級別,並鑽取到特定路徑(客戶端使用的路徑當它關閉時)。客戶端的緩存是持久的,所以所有的請求都是有條件的,而且很少有新的表示通過連線,並且刷新可以通過完全關閉緩存在後臺異步完成。 – mogsie 2010-07-14 22:59:20

+0

我同意將「API」建模爲客戶端應用程序的需求可以提供有效的會話,但我認爲重點在於API經常適用於許多客戶端,而不僅僅是一個客戶端。 – mogsie 2010-07-14 23:01:55

+0

@mogsie在許多情況下,爲多個客戶端構建API可能是可能的,但我認爲在大多數情況下,爲特定情況構建API效率更高。偶然的重用是REST旨在提供的,而不一定是有計劃的重用。 – 2010-07-15 01:11:32

0

我不認爲是這樣的嚴格要求。根據我的理解,客戶直接訪問資源並從此開始是合法的。重要的是,您不需要爲狀態轉換執行此操作,即在/ foo1等操作之後不會自動繼續處理/ foo2。最初檢索/ products/1234編輯它似乎非常好。服務器總是可以返回,比如重定向到/ shop/products/1234以保持向後兼容(這對於搜索引擎,書籤和外部鏈接也是可取的)。

4

是的,客戶端應用程序應該遍歷鏈接是正確的,但是一旦發現資源,保留對該資源的引用並使用它的時間比一個請求更長時間沒有任何問題。如果你的客戶有永久記憶的可能性,它可以這樣做。

考慮網絡瀏覽器如何保留其書籤。您可能在瀏覽器中可能會有一百或者一百個書籤,並且您可能在頁面層次結構中發現了其中的一些,但瀏覽器盡職地記住了它們,而不需要記住它們找到它們的路徑。

更豐富的客戶端應用程序可以記住sub1sub1sub1sub1的URI,並在它仍然有效時重用它。它很可能仍然代表着同樣的事情(它應該)。如果因任何其他客戶原因(4xx)不再存在或失敗,您可以重新執行步驟以查看是否可以找到合適的替代品。

當然Darrel Miller說:-)

+1

我喜歡你的比喻。有這樣的想法,一切都連接在一起,不能連接的東西。谷歌在這個意義上成爲所有導航的根源,但人們總是保存捷徑(書籤)。但是,如果你不在谷歌那麼你基本上不存在。 – Alex 2014-12-10 16:53:07

+0

謝謝。或者,更確切地說:如果谷歌沒有路徑到頁面,它就不存在。有點像這個謎語:「如果一棵樹落在一片森林裏,沒有人在那裏聽到它,它會發出什麼聲音?」 – mogsie 2014-12-17 09:30:29