What you'll learn
- With versioning on, every write creates a new version and a delete adds a delete marker instead of removing data.
IfNoneMatch: "*"makes a PUT create-only;IfMatch: etagmakes it update-only-if-unchanged.- A failed condition returns
412 PreconditionFailed— handle it as a normal outcome.
Section 01
Versioning
Turn on versioning with PutBucketVersioning. From then on each PUT gets a new VersionId, and older versions stay (and are billed) as noncurrent versions. A bucket can be unversioned, versioning-enabled, or versioning-suspended — once enabled, it can never go back to unversioned.
A DELETE without a version ID adds a delete marker: GET now returns 404, but every version is still there. Delete the marker and the object is back. Only a DELETE with a specific VersionId removes data permanently.
Section 02
Conditional writes
Versioning lets you recover from a lost update; a conditional write prevents it. S3 checks the condition atomically on the server, so no read-then-write race is possible.
| Header | Meaning | Use it to |
|---|---|---|
IfNoneMatch: "*" | Write only if no object has this key | Create a card exactly once |
IfMatch: "<etag>" | Write only if the current ETag matches | Update a card you just read, without clobbering someone else's edit |
Both work on PutObject and CompleteMultipartUpload. If another write to the same key is in flight, S3 may answer 409 ConditionalRequestConflict — retry.
const current = await client.send(new GetObjectCommand({ Bucket, Key }));
const card = JSON.parse(await current.Body.transformToString());
card.types.push("ground"); // Marshtomp evolves!
try {
await client.send(new PutObjectCommand({
Bucket, Key, Body: JSON.stringify(card), ContentType: "application/json",
IfMatch: current.ETag,
}));
} catch (err) {
if (err.name === "PreconditionFailed") { /* someone else changed it: re-read and retry */ }
else throw err;
}Practice
Your turn
Two researchers upload Mudkip's card at almost the same moment. Make your upload create-only, so it fails instead of replacing a card that already exists, and handle that failure.
IfNoneMatch: "*" and catch the PreconditionFailed error.Check
Check your understanding
Quick Quiz · one question, as many tries as you need.
DeleteObject on cards/0258-mudkip.json without a version ID. What happens?Choose one answer.