2013-11-15 54 views
0

通過RESTful最佳服務,HATEOAS原則告訴我們,我們不應允許客戶端構建資源URL-s。如果我們遵循這個原則,分享當前客戶的狀態將會非常困難。例如,如果你在服務器上有一個REST服務,並且你通過AJAX和一個頁面javascript客戶端獲得數據,那麼你將有2個URL。一個用於客戶端狀態,另一個用於從REST服務獲得的結果。由於pushState,只能共享客戶端狀態和使用情況......如果有人使用先前共享的URL運行客戶端,那麼她的客戶端將不知道應該調用的REST服務的URL,因爲客戶端無法構建URL-s,只需從REST服務接收並使用它即可。RESTful客戶端 - 如何處理外部鏈接?

例如:

  • 我瀏覽http://my.client.com
  • 頁面獲取從http://my.api.com根資源,並返回一個鏈接
  • 的鏈接包含http://my.api.com/users網址,使用rel用戶採集
  • 之後,客戶端顯示一個帶有標籤的按鈕:userlist
  • 我點擊那個按鈕,客戶端從api獲取數據,並打印TS用戶列表
  • ,如果我想和我的女朋友分享用戶列表中,然後我不得不瀏覽器的URL從pushState的客戶端改變,例如從http://my.client.com到後http://my.client.com/users
  • 我發送鏈接到我的女朋友
  • 她複製粘貼到她的瀏覽器地址欄並按下輸入。之後,該客戶說一個巨大的跆拳道,因爲 - 像斯諾 - 因此它不知道什麼狀態URL意味着...

這個問題是可以解決的,如果我們允許客戶端從URL建立GET http://my.api.com/usershttp://my.client.com/users,但這不會RESTful,因爲客戶端不應該建立API網址...

如果我想在客戶端顯示一個嵌套的菜單,那是另一個問題,因爲我不想在每個答案中發送整個菜單樹。我可以爲每個資源創建一個菜單投影,或者使用OPTIONS方法或自定義方法來發送這些數據,但這會讓人感到痛苦。這可以通過跟隨rel=up鏈接 - 從REST服務獲得 - 系列中解決,但如果我不知道應該從哪裏跟蹤,它將無法工作...

此問題也是由谷歌機器人...

我該如何解決這個問題,並保持在HATEOAS原則的界限之內?

+0

「my.client.com」的用途是什麼。難道你不能把你的網頁瀏覽器指向「my.api.com」。您似乎正在構建兩個客戶端,瀏覽器和客戶端服務正在某處運行。你正在鏈接客戶。這似乎正在重塑車輪。 Web瀏覽器已經是HTTP客戶端。 –

+0

REST服務應該是無狀態的,所以我必須使用客戶端來存儲狀態......通過一個普通的web應用程序,你是對的,但這是一個REST風格的web服務...... – inf3rno

+1

所以my.client.com/users是真的在單頁網頁應用上使用JavaScript的命令,而不是對外部服務的調用。在這種情況下,客戶端JavaScript應該根據該命令重建其對服務器的知識。應該說用戶需要用戶,所以我將從根my.api.com開始,找到用戶的鏈接,這可能是/用戶或可能是其他用戶,在該資源上執行GET並將其顯示給用戶。用於向瀏覽器中運行的JavaScript提供命令的URI與服務器上的URI無關。 –

回答

1

通常情況下,我們不希望分享所有的與任何人的資料,所以我們不能導出所有,只是當前頁面,我們在。

沒有什麼錯存儲整個資源,然後將其推送到服務器以更改服務器上的狀態。如果你擔心你的資源變得太大,儘管你可能會分配一些資源。所以說你有一個訂單資源,並且需要與一個地址關聯。您不需要將地址放在訂單資源中,只需要鏈接到要使用的地址即可。用戶可以獨立地添加或更改該地址。所以,你可能有類似

www.myapi.com/users/1234/shippingaddresses/default 

而且客戶可以把一個新的地址,此資源。然後在訂單資源的身體,你可以擁有這個資源的鏈接

POST www.myapi.com/users/1234/orders 
{ 
    ...order information... 
    "shipping_address": "www.myapi.com/users/1234/shippingaddresses/default" 
} 

要REST風格的客戶端不應該建立一個URL,它應該已經由服務器給它在某一點在最近的過去,可能在用戶選擇使用哪個地址時。例如,在上一步客戶端可能要求所有地址

GET www.myapi.com/users/1234/shippingaddresses 

並在下拉列表中向用戶呈現地址列表。

+0

我認爲有一個誤解。是的,它允許在客戶端存儲和顯示資源狀態。我的意思是我們通常不希望將所有信息存儲在瀏覽器地址欄中。例如,通過在網上商店中瀏覽目錄,您希望在地址欄中包含當前的產品ID(用於複製粘貼,並將其與某人分享作爲鏈接),但您不想具有所有詳細信息關於您當前購物車中的內容,或者您​​的會話ID,個人信息等等......所以我們通常只想分享有關REST客戶端狀態的部分信息...... – inf3rno

+0

雖然REST客戶端不應該'沒有任何獨立於服務器的狀態。客戶端從服務器拉下狀態,修改它並將其推回。您不應將客戶端之間的複雜狀態獨立於服務器。您應該在客戶之間分享的最多的內容可能是您正在查看的最後一個資源的書籤。所有狀態都應該通過服務器,如果必須共享狀態,則必須將其推送到服務器,並讓另一個客戶端從服務器上將其拉下。從客戶端複製狀態到客戶端查看諸如複雜URI之類的東西是個不錯的主意。 –

+0

你對很多事情都是對的,所以我刪除了我可能不好的答案(沒有耐心閱讀它),而是接受你的答案。修復我的舊帖子是一項艱鉅的工作......:S – inf3rno