diff --git a/db-controller.js b/db-controller.js index 8e7ed7b5..f794278d 100644 --- a/db-controller.js +++ b/db-controller.js @@ -982,6 +982,9 @@ const id = async function (req, res, next) { res.set("Cache-Control", "max-age=86400, must-revalidate") //Support requests with 'If-Modified_Since' headers res.set(utils.configureLastModifiedHeader(match)) + // Include current version for optimistic locking + const currentVersion = match.__rerum?.isOverwritten ?? "" + res.set('Current-Overwritten-Version', currentVersion) match = idNegotiation(match) res.location(_contextid(match["@context"]) ? match.id : match["@id"]) res.json(match) diff --git a/public/API.html b/public/API.html index 1eaebd7a..a3a56e83 100644 --- a/public/API.html +++ b/public/API.html @@ -809,13 +809,19 @@
RERUM allows the Generator of a record to overwrite that record. An error will be returned if the agent encoded in the request "Authorization" access token does not match the agent of the existing record.
-
Replace a record using a reference to its internal RERUM id and receive the Location URI for the resulting record as a response header and the complete record as the response body.
-
This will have the effects of update, set, and unset actions. New keys will be created and keys not present in the request will not be present in the resulting record.
-
The record is replaced in place, or overwritten, and so the @id will not change and the history connected with this record will not be altered. The __rerum.isOverwritten property will be set to the date and time of the overwrite.
+ This endpoint supports optimistic locking, if requested. Including the "If-Overwritten-Version" header with the
+ value of the __rerum.isOverwritten property of the
+ record will cause the request to fail if the record has been overwritten since that time.
+ This is useful for preventing overwriting a record that has been changed by another agent, colliding within an
+ application that rapidly requests overwrites of the same object, or if an object is held in memory or cache for a
+ long time prior to the overwrite. Omitting the "If-Overwritten-Version" header or __rerum.isOverwritten
+ property will cause the request to succeed regardless.
+