Concurrency, etags and caching
A site has more than one editor — a person in the admin, your integration, a scheduled
job — and the default outcome when two of them save the same page is that the later write
wins and nobody is told. The etag every resource carries is how you opt out of that.
Read it with the resource, send it back in If-Match, and a write that lost the race is
refused instead of applied:
Code
The refusal is a 409 with ABORTED and the current resource in the body, so a client
has everything it needs to show the conflict — or to merge and retry — without a second
request. Without If-Match the write is unconditional, which is fine for a field only you
own and wrong for anything a person also edits.
The same value works on the way in: a GET with If-None-Match answers 304 when
nothing changed, so a poller pays for headers rather than for a body.
14. Concurrency and etags
- A resource with concurrent editors MUST expose an
etag, computed over its persisted state. - A client MAY send
If-Match: "<etag>". If the stored etag differs, the write failsABORTED(409) and the response body carries the current resource. - A resource MAY require
If-Matchon Update and Delete. It MUST document which. etagMAY also be echoed as an HTTPETagheader. The field is the contract; the header is a convenience.
16. Caching and conditional reads
- A
GETwithIf-None-Matchmatching MUST return304with no body. - Mutating responses are
Cache-Control: no-store.