想象一下,一個網絡應用程序存儲一些數據資源,這些數據資源有一些id,每個數據存儲三個附件(例如pdf)。多個資源的RESTful原子更新?
的URL方案是
data/{id}/attachment1
data/{id}/attachment2
data/{id}/attachment3
的REST風格的API存在提供GET/PUT附件/ DELETE在服務器端執行CRUD操作操作。
又讓ID是123,想以執行其中
- 附件1由一個新的附件替換一個操作(使得
GET file/123/attachment1
返回一個新的附件) - attachment2被刪除(使得即
GET file/123/attachment2
返回404) - attachment3保持不變。
該更新應該是原子 - 完整的更新是由服務器執行或根本沒有。
應用簡單的PUT file/123/attachment1
和DELETE file/123/attachment2
不是原子的,因爲在PUT之後客戶端可能會崩潰,並且服務器沒有提示他應該在這種情況下進行回滾。
那麼如何以RESTful的方式實現操作?
我想過兩種解決方案,但他們似乎都沒有100%的RESTful:
- 使用Patch(可放,但PATCH能更好地反映的 的部分更新的語義)與多/表格數據/ 123:多部分/表格數據是由與字段「attachment1」和 相關聯的新的 「application/pdf」組成的實體序列,其將代表空值以表示空值刪除 附件2。
雖然這確保了原子性,但我懷疑這是RESTful,因爲我使用不同的參數列表來重載PATCH方法,這違反了統一接口約束。
- 使用表示事務的資源。我可以將數據ID 123 發佈到事務URL,該事務URL將創建表示服務器上存儲的數據資源 的當前狀態的副本的事務資源 ,例如,交易/數據/ 123。現在我可以調用PUT和 DELETE這個臨時資源的附件(例如
DELETE transaction/data/123/attachment2
)並且通過 transaction/data/123將此版本的資源提交到服務器的服務器通信 。這確保了原子性,同時必須實現額外的服務器端邏輯來處理多個客戶端 更改相同的資源和崩潰的客戶端永遠不會提交。
雖然這似乎與REST一致,但似乎違反了無國籍的限制。事務資源的狀態不是服務狀態,而是應用程序狀態,因爲每個事務資源都與單個客戶端相關聯。
我有點卡在這裏,所以任何想法會有所幫助,謝謝!
第二種方法的好處是提供了一個很好的數據更改歷史記錄,並可能允許您跳過某些日誌記錄。 – Jasper 2012-04-06 07:07:37
@mtsz我現在正在努力解決這個問題。我喜歡下面選擇的答案,但創建短暫的臨時生命週期的交易資源似乎有很多工作要做。你認爲給原子事務執行一個像「switcheroo」這樣的名稱並創建一個執行該事務的特定Web服務會很糟糕嗎?例如,具有{fileId:123}的主體的POST/doSwitcheroo ....該服務將具有邏輯地以文件形式執行上面在ID爲123的文件中描述的動作012 – 2015-11-11 02:22:57