Documentation Index
Fetch the complete documentation index at: https://docs.larksh.com/llms.txt
Use this file to discover all available pages before exploring further.
Lark supports conditional writes using ETags. This gives you compare-and-swap (CAS) semantics over HTTP: write only if the data hasn’t changed since you last read it.
How it works
- Read data and request its ETag.
- When you’re ready to write, include the ETag in your request.
- If the data has changed since you read it (ETag mismatch), the write fails with
412 Precondition Failed.
- If the data is unchanged, the write succeeds.
This prevents lost updates when multiple clients or servers are writing to the same path.
Getting an ETag
Add the X-Firebase-ETag: true header to any GET request:
curl -i \
-H 'X-Firebase-ETag: true' \
'https://chess-app.larkdb.net/my-game/players/alice.json?auth=YOUR_TOKEN'
Response headers include the ETag:
HTTP/2 200
ETag: "a1b2c3d4e5f6..."
Content-Type: application/json
{"name":"Alice","score":250,"online":true}
The ETag is a SHA-256 hash of the data’s canonical JSON representation.
Conditional write
Include the ETag in an If-Match header on your write:
curl -X PUT \
-H 'If-Match: "a1b2c3d4e5f6..."' \
'https://chess-app.larkdb.net/my-game/players/alice/score.json?auth=YOUR_TOKEN' \
-d '300'
Success
If the ETag matches (data hasn’t changed), the write succeeds normally:
Conflict
If someone else modified the data between your read and write, you get a 412:
HTTP/2 412
{"error":"condition_failed","message":"ETag mismatch"}
The response body contains the current value and the response includes the updated ETag, so you can read the new state and retry.
Retry pattern
A typical conditional update loop:
async function incrementScore(projectUrl: string, path: string, token: string) {
const url = `${projectUrl}/${path}.json?auth=${token}`;
while (true) {
// 1. Read with ETag
const readResponse = await fetch(url, {
headers: { 'X-Firebase-ETag': 'true' }
});
const etag = readResponse.headers.get('ETag');
const currentValue = await readResponse.json();
// 2. Compute new value
const newValue = (currentValue ?? 0) + 1;
// 3. Conditional write
const writeResponse = await fetch(url, {
method: 'PUT',
headers: { 'If-Match': etag! },
body: JSON.stringify(newValue)
});
if (writeResponse.ok) {
return newValue; // Success
}
if (writeResponse.status === 412) {
continue; // Conflict — retry with fresh data
}
throw new Error(`Unexpected status: ${writeResponse.status}`);
}
}
When to use conditional requests
Conditional writes are useful for:
- Incrementing counters and balances without risking double-counts.
- Optimistic locking: let a user edit data and reject stale writes.
- Server-side read-modify-write operations without holding a persistent connection.
For client-side compare-and-swap, transactions in the Lark SDK provide a more ergonomic API with automatic retries.