每個用戶都有一個寶石集合。這些寶石可以通過REST API來訪問:REST - ETag在POST到資源收集和If-Match標頭時
GET /user/<user id>/gem -> get all gems
GET /user/<user id>/gem/<gem id> -> get an existing gem
POST /user/<user id>/gem -> add a new gem
PUT /user/<user id>/gem/<gem id> -> edit an existing gem
DELETE /user/<user id>/gem/<gem id> -> delete an existing gem
我有幾個後端進程,這同時運行,並可能通過POST
HTTP方法添加寶石。 (他們也可以編輯(PUT
)或刪除(DELETE
)寶石,但這對我的問題並不重要,實際上是這樣,請繼續閱讀。)
從高層次看,他們做了以下:
1. GET /user/<current user id>/gem
2. some calculations, based on step 1
3a. if (step 2 decided that a gem should be added)
3b. POST /user/<current user id>/gem
如前所述,這些過程並行運行。通常,兩個進程不管理同一用戶的寶石,但可能會發生。
所以我需要一種機制,在步驟3b
中禁止POST
,如果在此期間有所改變。我想過使用ETags和樂觀鎖定:
1. GET /user/<current user id>/gem and remember the returned ETag
2. some calculations, based on step 1
3a. if (step 2 decided that a gem should be added)
3b. POST /user/<current user id>/gem with header 'If-Match=<ETag from step 1>'
3c. if (server returns 412 - precondition failed)
3d. start again at step 1
我不確定ETag是否適用於此目的。 ETag的大多數示例都是關於一個資源(如/gem/23
),但不是關於資源集合(如/gem
)。也就是說,在步驟3b
中,我提供了完整寶石集合的ETag,而本質上我提供了一個要添加的寶石。
謝謝你在這裏使用弱ETag的提醒! –