2013-02-27 50 views
4

我在理念上很難理解關於版本化資源URL的真實情況。不同版本的資源的REST風格的URL

比方說,我有一個跟版本控制系統類似的跟蹤食譜的應用程序,就像RCS之類的舊學校一樣。每個版本都可以是一段時間的工作副本,然後再創建一個新版本。每個版本都有與其相關的評論,並且不會共享評論。我可以在任何時候回顧歷史,看看配方的演變過程,但每個實例總是被視爲相同配方的一個版本。我試圖找出最合適的方式來構建URL來引用這些,並且我很難理解類似子資源和時間資源等之間的一些差異。

我已經看到了這一點做的兩種主要方式是:

> 1) query parameters 
> -- /recipes/ultimate-thing    -> List of available versions of Ultimate Thing 
> -- /recipes/ultimate-thing?version=2  -> Version 2 of Ultimate Thing 
> -- /recipes/ultimate-thing?version=latest -> Current working version of Ultimate Thing 

2a) Nested resources with versions considered subresources 
-- /recipes/ultimate-thing/versions/  -> List of available versions of Ultimate Thing 
-- /recipes/ultimate-thing/versions/2  -> Version 2 of Ultimate Thing 
-- /recipes/ultimate-thing    -> Current working version of Ultimate Thing 

2b) Nested resources with the list at the resource 
-- /recipes/ultimate-thing     -> List of available versions of Ultimate Thing 
-- /recipes/ultimate-thing/versions/2  -> Version 2 of Ultimate Thing 
-- /recipes/ultimate-thing/versions/latest -> Current working version of Ultimate Thing 

我覺得每次我試圖說服的做這件事的一種方式我自己我覺得我缺乏瞭解,構建一個適當的理由爲那個方法。

1似乎被很多rails用戶所青睞,但我不知道如何清楚自我POST到特定資源後何時創建新版本配方(/recipes/ultimate-thing)通常希望創建具有該名稱的資源(如果該資源不存在),是否適合返回404而不是創建它,並且只發布到/食譜以創建新配方然後允許郵政/食譜/終極東西創建一個新版本?另外,評論如何表示?沒有版本我可以做類似/食譜/最終的東西/評論,但/食譜/ utlimate-things /評論?版本=最新似乎醜陋,而2b似乎更明確「評論最新版本的終極事物配方「,2a似乎是最乾淨的。

其實,我一般喜歡2A最好的,但我無法搞清楚這版本的食譜子資源因爲沒有菜譜,一個版本配方而是食譜的所有版本應該進行邏輯分組一起。

我也在這裏看到了2b的stackoverflow,但它似乎可能過於冗長,因爲你總是需要像/recipes/ultimate-things/version/latest/comments之類的東西。儘管如此,如果我將版本看作是可以註釋說明的成分集合,並且配方是共享類似意圖的版本集合,那麼這確實是最有意義的。

我真的很喜歡2a,但有沒有什麼東西與我失蹤的方法,這是一個壞主意?我是否錯過了一個如何工作的東西,這使得它似乎更受衆多人的青睞?

或者,它將使更多的意義,總是做這樣的事情/食譜/最終-事/最新/食譜/最終-事/ 2 /評論即使,使得它的至少明確,這些都是同一配方的不同修訂?

我不確定這是否是一個超級適合的論壇,我只想討論它,所以我明白爲什麼一種方法會比另一種更好。

回答

4

哇。好問題。我也發現REST最大的挑戰之一是它是一種風格,而不是嚴格的規範。這種風格似乎沒有得到很好的理解,沒有什麼能夠強化它。

簡短的回答:風格#1:/食譜/餅版本= 2

這種風格似乎最適合我的。只是在Google的快速搜索之後,我發現查詢參數被認爲是URI的一部分。因此,在URI中放置標識屬性似乎是適當的。

樣式2和樣式3似乎違反了路徑段代表ID和子資源的其他REST約定。因此,風格/食譜/蛋糕/ 2看起來像ID的「蛋糕」資源2/食譜/蛋糕/版本/ 2使「版本」似乎是一個子資源,在當實際上它是父資源的一個屬性。

+0

雖然這似乎是最合理的解決方案,將它作爲一個參數,真正解決應該使用該版本作爲資源獲取的另一個元數據,類似於MIME類型。爲什麼通過Accept頭協商內容,而不是通過另一個頭協商版本? – 2013-02-27 22:50:03

+0

@DiegoSevilla我公開承認我的建議是基於觀察到的慣例的意見。 REST的許多方面(動詞,狀態代碼)都由HTTP規範明確定義,並不打算解釋。我沒有看到規範中的任何內容,但它定義了一個URI標準(我也只是剔除了它).....所以我對你的問題是 - 你建議使用HTTP標頭(a)約定還是(b)由HTTP規範建議的東西。 – EJK 2013-02-27 23:21:19

+0

@DiegoSevilla - 請重新閱讀您的問題「爲什麼通過Accept頭協商內容,而不是通過另一個頭協商版本」。我的答案是Accept頭可以確定資源的表示形式。將版本放在URI中標識資源本身。是的,我假設不同的版本在概念上是不同的資源。 – EJK 2013-02-27 23:23:54

3

我只是在去年年底實施這種模式,並遵循2a和2b的組合:

2c) Nested resources with versions considered subsets 
-- /recipes/ultimate-thing/versions/  -> List of available versions of Ultimate Thing 
-- /recipes/ultimate-thing/versions/2  -> Version 2 of Ultimate Thing 
-- /recipes/ultimate-thing/versions/latest-> Redirect to current working version of Ultimate Thing 

不要以爲長的URI爲「子資源」或「屬性」,彷彿一個URI標識一個東西。將URI作爲標識數據是更自然的,並且由於HTTP URI是分層的,所以更長的URI是指數據的子集。集合中的項目是數據:集合中所有數據的子集。 「事物」的「屬性」是數據:關於該事物的所有數據的子集。 「子資源」是有關「事物」的數據,它不是獨立於其父級而存在的,因此是有關父級的所有數據的子集。

對於您的情況,您不必執行太多的心理柔道就可以將recipes/cherry-pie/視爲有關櫻桃餡餅是什麼以及如何製作櫻桃派的所有數據,而不是特定版本的說明。這包括身份信息和其他非特定於版本的數據,但也包含指向versions/的鏈接,並鏈接到歷史記錄和有趣的視頻,其中有人獲得了該視頻。 URI recipes/cherry-pie/versions/然後是所有櫻桃派數據的子集,一般來說,它只不過是鏈接到形式爲recipes/cherry-pie/versions/{version}/的每個URI的鏈接集合。我還會在versions/中包含一個到recipes/cherry-pie/versions/latest/的文檔鏈接,它會暫時重定向到recipes/cherry-pie/versions/182/或任何最新版本。

這對客戶非常自然。許多人絆倒他們看到的資源爆炸,並認爲可憐的客戶不可能跟上。但是,如果您沿着自然用戶工作流邊界劃分資源,則不會有問題。有些客戶需要瀏覽一組食譜;有些將深入到單一配方(不管版本);有些人會深入研究,想知道有多少版本,哪一個是最新版本,並從中選擇;有些會鑽取並檢索單個版本。如果您想要顯示單個配方或所有配方的所有版本,則可能是做錯了事情(在極少數情況下,您不會設計另一個資源,如recipes/byname/pie/quickview,它收集所有數據並將其緩存重)。

+0

這似乎是一個非常有趣的REST API思考方式,我需要考慮這個以及我在@EJK上進行的其他討論。很多用於處理版本化模型的框架將建議樣式1,其中每個版本都是帶有版本ID字段的整個模型,但從邏輯上講,我認爲沿着一個配方的路線是一個收集成分和指令列表版本的實體追蹤歷史,因爲這些都是在版本控制或rolodex中工作的。 – Sloloem 2013-02-28 18:52:55

0

這一切都取決於你如何看待資源版本。這些只會用於維基的歷史追蹤或版本是單獨的資源。在第一種情況下,EJK answer似乎是一個很好的解決方案。對於爲資源版本/變體創建新的唯一標識符的第二種情況可能是另一種解決方案。 例如:

3) Resources with versions 
-- /recipes/       -> List of available recipes versions 
-- /recipes/ultimate-thing-version-2 -> Version 2 of Ultimate Thing 
-- /recipes/ultimate-thing   -> The "offical" version of Ultimate Thing 

這更是首選的解決方案,如果資源是相互的變化:

3) List of recipes 
-- /recipes/       -> List of available recipes and variations 
-- /recipes/ultimate-thing-with-sugar -> The Ultimate Thing recipe with sugar 
-- /recipes/ultimate-thing-with-honey -> The Ultimate Thing recipe with honey