2011-01-05 20 views
11

HATEOAS(超媒體作爲應用程序狀態的引擎)建議是否暗示查詢字符串不是RESTful?HATEOAS是否暗示查詢字符串不是RESTful?

編輯:下面建議查詢字符串可能與狀態沒有太大關係,因此問題令人費解。我建議,除非客戶端正在填寫參數,否則URI沒有任何意義。如果客戶端正在填充參數,那麼它會摻雜服務器提供的URI,我想知道這是否違反了RESTful原則。

編輯2:我意識到查詢字符串似乎無害,如果客戶端將其視爲不透明(和查詢字符串可能是遺留的,因此方便)。然而,在下面的一個答案中,引用了Roy Fielding的觀點,認爲URI應該被認爲是透明的。如果它是透明的,那麼我認爲摻雜是被鼓勵的,這似乎淡化了HATEOAS原則。這種稀釋是否與HATEOAS一致?這引發了REST是否在呼籲URI構建似乎是緊密耦合的問題。

更新在此REST教程http://rest.elkstein.org/中,建議URI構建是不好的設計並且不是RESTful。它也重複了@zoul在接受的答案中所說的話。

例如,「產品列表」請求可能會返回每個產品的ID,並且規範說明您應該使用http://www.acme.com/product/PRODUCT_ID以獲取更多詳細信息。這是糟糕的設計。相反,響應應該包括每個項目的實際URL:http://www.acme.com/product/001263等。是的,這意味着輸出更大。但這也意味着您可以根據需要輕鬆地將客戶端導向新網址

如果某人正在查看此列表並且不希望他/她能夠看到的內容,則可能會出現「前10項」然而,如果沒有人工,而是一個客戶程序,「下一個10個項目」按鈕,REST的這個方面似乎有點奇怪,因爲客戶端程序可能沒有用的所有「http://www」。

回答

4

我會建議它不會使 意義的URI有一個查詢字符串 除非客戶是在參數填充 。

這似乎對我來說不正確。如果你問服務器的照片了一把,這是完全合法的服務器返回的東西是這樣的:

<photos> 
    <photo url="http://somewhere/photo?id=1"/> 
    <photo url="http://somewhere/photo?id=2"/> 
</photos> 

你可以使用/photo/id/xx路徑,而不是,但是這不是問題的關鍵。即使沒有客戶更改它們,這些URL也是可用的。關於你的第二點:

如果客戶填寫參數 則摻假的 服務器提供的URI,我不知道如果 這違反了REST的原則。

我想這是你的問題的核心。我不認爲你必須把網址作爲不透明標識符,看到羅伊·菲爾丁this quote自己:

REST不要求一個URI是 不透明。我的論文中唯一發生不透明詞 的地方是 ,我抱怨cookie不透明 。事實上,基於REST的 應用,在任何時候, 鼓勵使用人有意義, 分層標識符以 最大限度地超出了預期 由原始應用程序的偶然使用的 信息。

+1

聽起來像是越野車軟件有可能通過對「有意義」的標識符進行可能有缺陷的解釋而被寫入。爲了防止有缺陷的解釋,看起來帶外信息是正確構建URI所必需的。如果需要帶外信息修改鏈接,那麼超媒體必須推動應用程序的狀態有什麼意義?如果您需要帶外信息,那麼爲什麼還要讓服務器發送一堆鏈接呢? – H2ONaCl 2011-01-05 14:36:22

+0

好的,爲了回答我自己關於服務器發送鏈接的問題,我知道最好讓客戶端只使用一個衆所周知的資源,因此發送鏈接的服務器是一個好主意,並且查詢字符串可能對歷史很方便或者因爲它們映射到網關另一側的傳統名稱空間。然而,對於菲爾丁來說,他希望最大限度地偶然使用URI與鼓勵人們查詢字符串(安全地通過使用帶外信息或不安全地)是不完全相同的。這是查詢字符串,是我關心的核心。 – H2ONaCl 2011-01-05 14:50:18

+1

處理查詢字符串看起來像緊密耦合。 REST是否真的鼓勵緊密耦合? – H2ONaCl 2011-01-05 14:56:39

2

我沒有看到查詢字符串與狀態跟蹤有什麼關係。 HATEOAS原則的要點是避免跟蹤客戶狀態,從「欺騙」到「已知」URL數據。這些URL是否具有查詢字符串似乎與我無關。

哦。也許你對搜索網址感興趣,其中URL的某個部分必須根據搜索條件進行更改?因爲這樣的URL似乎必須事先知道,因此表示我們試圖用REST消除的帶外信息?我認爲這可以通過使用URL模板來解決。例如:

client -> server 
    GET /items 
server -> client 
    /* …whatever, an item index… */ 
    <search by="color">http://somewhere/items/colored/{#color_id}</search> 

這種方式你不需要先驗URL的知識進行搜索,你應該忠實於超媒體狀態跟蹤原則。但是我對REST的掌握非常薄弱,我主要是回答我腦海中的問題並獲得反饋。當然有更好的答案。

+0

Re:搜索,如果您願意將特定搜索建模爲其自己的資源,那麼您可以將URL創建委託給服務器。例如,'POST'是查找項目的部分表示(你知道的所有項目,例如'{「id」:37}')到'/ items/search',服務器可以用'鏈接:; rel = results'標題。這樣客戶端永遠不必組裝一個URL。(這個建議是基於這樣的想法,即內容類型和鏈接關係必須是REST應用程序的公共合約的一部分,客戶端才能夠使用該應用程序。) – stakx 2015-06-21 15:46:13

2

否HATEOAS並不意味着查詢字符串不是RESTful。事實上恰恰相反可以是這種情況。

考慮用戶嘗試訪問受保護資源並將它們發送到登錄屏幕時的常見登錄情況。登錄屏幕的URL通常包含名爲redirectUrl的查詢字符串參數,該參數告訴登錄屏幕在成功登錄後返回到哪裏。這是使用URI來維護客戶端狀態的一個例子。

下面是在URL中存儲客戶端狀態的另一個示例:http://yuml.me/diagram/scruffy/class/[Company] <> -1> [Location],[Location] + - [Point ]

+0

但是,查詢字符串指示「在哪裏返回成功登錄「不是一個URI,所以看起來HATEOAS被侵犯了。 – H2ONaCl 2011-01-05 13:22:39

+0

登錄網址是一個URI。重定向查詢字符串參數是一個URI。我不明白你認爲什麼約束被違反。 – 2011-01-05 13:47:34

+0

好的,我明白你在說URI裏面有一個URI。 – H2ONaCl 2011-01-05 14:11:19

5

我認爲REST本身並沒有說明URI是不透明還是透明的,但REST應用程序不應該依賴於客戶端來構造服務器尚未告知它的URI。服務器執行此操作的方式有很多種:例如,可能包含指向其成員的鏈接的集合,或者使用GET方法的HTML表單顯然會導致帶有參數的URI在客戶端創建並獲取,或者至少有一些URI模板的建議標準。 REST的重要之處在於,服務器應該在給客戶端的響應中以某種方式定義有效URI的描述,而不是在某些帶外API文檔中定義的有效URI的描述

URI透明是一件好事與任何地方的透明度相同的方式是一件好事 - 它促進並允許超出設計者最初設想的資源的新穎和未計劃的用途 - 但(至少在我的理解中)好的URI不是要求將接口描述爲RESTful

+0

我對此的理解是:可發現性和「超媒體作爲應用程序狀態的引擎」並不意味着構建URI(或者就此而言,任何特別是人類可理解的URI集合)的構建方法。根據我的理解,基於客戶端發現狀態的資源標識符的構建可以以任何可能的方式進行。 – 2011-06-01 20:20:34

6

在Roy Fielding的own words(文章中的第4個要點):

REST API不能定義固定的資源名稱或層次結構(客戶端和服務器的明顯耦合)。服務器必須有自由控制自己的命名空間。相反,允許服務器通過在媒體類型和鏈接關係內定義這些指令來指導客戶如何構建適當的URI,例如在HTML表單和URI模板中完成的。

換句話說,只要客戶端沒有得到它們需要在帶外信息中生成URI的部分,HATEAOS就不會被違反。


注意 URI模板可以URI中使用沒有查詢字符串,以及:

http://example.com/dictionary/{term} 

所以,問題是更多關於它是否是REST風格的允許客戶構建網址方面,比是否使用查詢字符串是RESTful。

請注意,上述示例中提供給客戶端的信息量如何爲完全等效爲,以便爲所有可能的術語提供詳盡的列表,但從帶寬的角度來看效率更高。

它還允許客戶端在尊重HATEAOS的同時搜索字典,這在沒有帶內指令的情況下是不可能的。我完全相信,羅伊菲爾丁不提倡網絡沒有任何搜索功能......


關於你的第三個評論,我覺得羅伊菲爾丁鼓勵API設計有「透明」的URI作爲一項額外功能:在HATEAOS之上。在zoul的回答中,我不會將他的引用解釋爲客戶會使用「常識」以明確的URI導航API。他們仍然會使用帶內指令(如表單和URI模板)。但是,這並不意味着透明URI不會比黑暗,令人驚訝,不透明的URI更好。

事實上,透明URI爲API提供了附加價值(調試是一種用例,我可以想到透明URI在哪裏是無價的)。


欲瞭解更多信息有關URI templates,你可以看看RFC6570

0

要從Darrel所說的後續操作,您不需要更改URL以包含第二個URL。

對於基於cookie的身份驗證,您可以使用空表單操作返回401響應正文中的登錄表單,並使用可以發佈到每個資源並由其處理的唯一字段名稱。這樣你就完全避免了重定向的需要。如果您不能擁有所有資源流程登錄請求,則可以將401表單操作指向登錄操作資源,並將重定向URL置於隱藏字段中。無論哪種方式,您都避免使用URL中的醜陋URL,並且第一種方法避免了RPC登錄操作和重定向的需要,從而使所有交互都集中在資源上。

相關問題