2012-02-07 95 views
8

假設我想要設計一個REST api來討論歌曲,專輯和藝術家(實際上我是這樣做的,就像1312414之前的人一樣)。RESTful處理資源之間雙向關係的方式

歌曲資源總是與它所屬的專輯相關聯。相反,專輯資源與其包含的所有歌曲相關聯。這些關聯通過鏈接在資源表示中表達。

因此,陳述會是這個樣子:

{ 
    song: 'xyz', 
    links: [ 
     { rel: 'album', url: '.../albums/abc' } 
    ] 
} 

{ 
    album: 'abc', 
    links: [ 
     { rel: 'song', url: '.../songs/xyz' }, 
     { rel: 'song', url: '...' }, 
     { rel: 'song', url: '...' }, 
     { rel: 'song', url: '...' } 
    ] 
} 

考慮,我想這是成立的(也許問題就出在「給定」),怎麼那麼我設計我的API ,使得專輯或歌曲資源的創建對先前存在的歌曲或專輯資源沒有副作用?

這是某種雞/雞蛋的問題。如果我首先創建歌曲資源(POST/songs /),然後創建專輯資源(POST/albums /),歌曲資源將作爲專輯創建的一部分進行修改(根據REST原則,這是不好的),因爲關聯兩個資源之間的服務器正在更新。同樣,對於我首先創作專輯的場景,其次是歌曲。

我想我可以通過避免服務器上的副作用並將管理雙向關係的負擔傳遞給客戶端來避免整個問題。

此外,我不希望專輯和歌曲作爲一個整體自動創建。

我現在唯一能想到的就是在API的語義中包含前面提到的副作用,通過使用一個表示來響應資源創建,該表示包含已修改爲請求的結果。這使副作用明確,但仍然不安寧。

+0

創建一首歌曲,如果它有一個專輯字段,並且該專輯不存在,請創建該專輯。創建一個專輯,如果它有一首不存在的歌曲,請創建歌曲。 – zzzzBov 2012-02-07 21:00:32

+0

查看它的一種方式是每個專輯,歌曲是一個封裝資源,鏈接只是將它們相互連接起來的圖形。更改鏈接會改變資源之間的關係,但資源實際上並未改變。 – abraham 2012-02-07 21:09:02

+3

「歌曲資源被修改爲專輯創建的一部分(根據REST原則,這是不好的)」這個原則是什麼?你能提供一個鏈接嗎?根據我的經驗,更新資源一直對其他資源有副作用。 – 2012-02-07 22:43:31

回答

1

REST說沒有關於操縱一個資源的狀態不能改變另一個資源的狀態。關於最接近的REST得到的是冪等動作的概念,它只是說重複它們會導致相同的狀態。

因此,就您的情況而言,Song資源能夠有效地將其自身添加到Album資源中,這本身並不存在任何不正確的錯誤。資源能夠說Song資源是其中的一部分,也沒有任何內在的錯誤。

現在,根據您的業務需求,您可能需要a。)更改歌曲/專輯或b的表現方式。)允許歌曲/專輯以m/m方式相關,而不是1/1。原因在於,根據您在系統中如何構建數據和選擇資源(即可尋址單元),實際上您建模的是不同的數據關係,我認爲這是您面臨的問題的關鍵。

使用SongsAlbums系統中的單獨資源強制實施更多限制性關係(如1/1而不是m/m)需要您的內容類型中有更多的工作和規範。你必須處理兩個不同專輯都認爲他們包含一首歌的情況,但1/1的關係不允許。

如果你有一個Album對象明確包含自己Song對象,那麼就不是一個問題,因爲一個Album只能操縱它自己的歌,而不是那些任何其他Album。這變化的數據模型,但是,因爲Songs不再是一流的公民,而是下面擁有它們的專輯。

這是整個問題的關鍵點... 你必須決定誰擁有關係

雙方並沒有錯(AlbumSong)擁有它。這適用於m/m關係,但對於1/1關係來說,這需要更多的管理開銷(即其他事實上擁有關係)。

如果不想所有的開銷1/1的關係,但是,你必須有參與實體擁有關係的一個,這意味着只有一個路徑改變它......通過擁有實體。