2012-07-06 110 views
0

我在我的REST服務器中建立了一個很好的資源層次結構,但是我有一個使我感到困惑的用例。如何跨多個父資源引用子資源?

我們有一個相當典型的項目/組設置,並引用所有組的一個項目是很容易的。不過,有時候,我希望所有具有特定狀態的羣體(跨所有項目)。這在標準的子資源層次結構中顯然是不可能的。

唯一干淨的解決方案我看到的是在同一時間有團體作爲一種資源和子資源(因爲它們是可尋址的一個獨特的密鑰)。我以前曾經考慮過這種「別名」資源的概念(以兩種不同的方式處理同一資源),但我不確定表達這一點的最佳方式。

回答

1

如果您希望您的應用程序不依賴於規模,最好將您的基本資源視爲唯一標識的實體(請參閱Helland),但允許將它們的索引公開。指數的最常見的形式是一個包含其項目,使用的HTTP URI的分層性質的集合:我們可以稱之爲

GET /groups/ 
    200 OK 
    {"entities": [ 
     "/groups/1/", 
     ... 
     "/groups/212/", 
     ], 
    } 

的「主索引」。但也有許多其他的可能性:

GET /projects/foo/groups/ 
    200 OK 
    {"entities": [ 
     "/groups/7/", 
     "/groups/182/", 
     ], 
    } 

GET /groups/by_status/ACTIVE/ 
    200 OK 
    {"entities": [ 
     "/groups/13/", 
     "/groups/64/", 
     ], 
    } 

謹慎使用這些替代指數,但是,因爲他們往往不同步的現實,尤其是當你把多個服務器和緩存到混合(讀埃蘭的紙) 。這就是爲什麼上面的示例輸出由鏈接組成,而不是原子實體本身的副本。出於同樣的原因,你不希望有兩個標識相同原子實體的URI。這將導致陳舊的數據和丟失的更新,因爲多個客戶端獲取相同數據的多個副本。

如果一個實體是由兩個不同的標識符,真正的身份,如數字ID和一個唯一的名稱,然後選擇一個要規範,並有其他重定向到它:

GET /groups/by_name/bar/ 
    303 See Other 
    Location: /groups/44/ 
+0

感謝您的參考,我會確保徹底閱讀它。爲什麼兩個URL會強制陳舊的數據,假設他們在同一臺機器上?他們最終會針對相同的緩存調用相同的加載方法。當然,你需要在多臺機器上保持多個緩存同步。 – JasonB 2012-07-09 17:43:35

+1

我的意思是HTTP緩存,它位於服務器和客戶端之間,而不是服務器後面。例如,如果客戶端獲取資源'/ groups/44'和'/ groups/by_name/bar',並將它們粘貼在本地HTTP緩存中,則向'/ groups/44'發佈PUT,它只會失效'/ groups/44'的緩存,但是'/ groups/by_name/bar'仍然會包含舊的數據。 – fumanchu 2012-07-09 18:49:36

+0

但是,如果您重定向,如上所示,那麼客戶端將只有一個副本緩存,並且PUT會使其正確無效。 – fumanchu 2012-07-09 19:41:58