2017-07-19 78 views
0

我想知道當您擁有包含子資源列表的資源時,哪個是最佳實踐。例如,您擁有資源作者,其中包含名稱,ID,生日和List書籍等信息。這本書目錄只與作者有關​​。所以,你有以下情形:從子資源列表中更新/添加/刪除項目的REST設計

  1. 你想要一本新書添加到圖書清單
  2. 你想從列表中
  3. 更新一本書的名字要從刪除一本書列表

SOLUTION 1

我搜遍這是正確的設計,我發現了多種方法。我想知道是否有標準的設計方法。我認爲設計的書上說來有以下幾種方法:

  1. 補充:POST /authors/{authorId}/book/
  2. 更新:PUT /authors/{authorId}/book/{bookId}
  3. 刪除:DELETE /authors/{authorId}/book/{bookId}

解決方案2

我的解決方案是隻有一個PUT方法完成所有這三件事情,因爲書籍列表只存在於對象作者中,而您是實際的更新作者。喜歡的東西:

PUT /authors/{authorId}/updateBookList(發送author對象內部的整體更新的圖書列表)

我發現在我的方案的多個錯誤。例如,從客戶端發送更多數據,在客戶端擁有一些邏輯,對API進行更多驗證,並且還依賴客戶端具有最新版本的Book List。

我的問題是:這是否反模式?

情況1.在我的情況下,我的API使用另一個API,而不是數據庫。使用的API只有一個「updateBookList」方法,所以我猜測在我的API中複製這種行爲也比較容易。這是否正確?

情況2.但是,假設我的API會使用數據庫,它會更適合使用SOLUTION 1嗎?

此外,如果你可以提供一些文章,書籍,你可以找到類似的信息。我知道這種設計不是用石頭寫的,但有些指導方針會有所幫助。 (例如:REST API Design Rulebook

+0

如果這是一個真正的問題,而不是作業,請記住,書籍可以有多個作者。一本書應該是真正的頂級資源。 –

+0

這是一個真正的問題,但在我的情況下,書籍列表只屬於一個作者。例如,如果您刪除作者,那些書籍將不再存在。 – green

+0

現在。如果業務需求發生變化,您可能會冒API風險。當然,只有你可以知道這有多可能。 –

回答

2

我會去第一個選項,並有單獨的方法,而不是堵塞一般PUT內的所有邏輯。即使您依賴的是API而不是數據庫,也只是第三方依賴關係,您應該可以隨時切換,而不必重構太多的代碼。

話雖這麼說,如果你要允許大量的書籍一次的更新,然後PATCH可能是您的朋友:

RFC 6902展望(定義修補程序標準),從客戶端的角度來看,API可以被稱爲像

PATCH /authors/{authorId}/book 
[ 
    { "op": "add", "path": "/ids", "value": [ "24", "27", "35" ]}, 
    { "op": "remove", "path": "/ids", "value": [ "20", "30" ]} 
] 
2

解決方案2聽起來很像老式的RPC在方法被調用執行一些處理。這就像一個REST反模式,因爲REST的重點是資源而不是方法。你可以在資源上執行的操作是由底層協議(在你的情況下是HTTP)給出的,因此REST應該遵守底層協議的語義(它的幾個約束之一)。

此外,REST並不在乎您如何設置您的URI,因此實際上沒有RESTful URL。對於自動化系統,遵循特定結構的URI與作爲URI的隨機生成的字符串具有相同的語義。儘管應用程序應該使用rel屬性,它給了URI一些應用程序可以使用的邏輯名稱。一個期望URL的某種邏輯組合的應用程序已經與API緊密耦合,因此違反了REST試圖解決的原則,即客戶端與服務器API的解耦。

如果您想通過PUT以REST方式更新(子)資源,您必須遵循put的語義,它基本上聲明接收到的有效內容會替換在更新之前在給定的URI處可訪問的有效內容。

PUT方法要求該目標資源的狀態是 創建取代與由封閉在所述請求消息的有效載荷的表示 定義的狀態。

...

在POST請求中的目標資源旨在根據資源的自己的語義來處理 封閉表示, 而在PUT請求封閉表示被定義爲 更換狀態的目標資源。因此,PUT 的意圖對於中間人來說是冪等的和可見的,儘管確切的 效果只能由原始服務器知道。

在問候部分更新RFC 7231指出部分更新是可能的,通過使用PATCH或者通過@Alexandru或通過直接在子資源發出PUT請求,其中所述有效載荷替換子資源的內容的建議與有效載荷中的一個相關聯。對於包含子資源的資源,這會影響部分更新。

部分內容更新是可能的通過 靶向與狀態的單獨識別的資源重疊的較大的資源的 部分,或通過使用 已經爲部分更新被特別定義(例如,不同的方法,所述 [RFC5789]中定義的PATCH方法)。

在你的情況,你可以因此直接通過PUT操作發送更新的書籍收藏的東西像一個.../author/{authorId}/books資源取代了舊的集合。因爲這可能不適合那些寫過很多出版物的作者PATCH可能更好。但請注意,PATCH需要原子和事務性行爲。要麼所有的行動都成功,要麼沒有。如果在操作的中間發生錯誤,則必須將所有已執行的步驟作爲角色。

關於您對進一步文獻的要求,SO並不是正確的地方要問這個問題,因爲這裏有一個自己的離題關閉/標記原因。