Skip to content

Commit 61e7638

Browse files
feat(docs): add documentation for background writes
Adds a new documentation page explaining how to perform background database operations using Cloudflare's `waitUntil` function. This new page includes: - An explanation of the "fire-and-forget" pattern. - Code examples for `insert`, `update`, and `delete` operations. The sidebar navigation has been updated to include a link to the new page.
1 parent bbd2510 commit 61e7638

File tree

2 files changed

+120
-0
lines changed

2 files changed

+120
-0
lines changed

docs/.vitepress/config.mts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export default defineConfig({
3030
{ text: 'Introduction', link: '/introduction' },
3131
{ text: 'Basic Queries', link: '/basic-queries' },
3232
{ text: 'Advanced Queries', link: '/advanced-queries' },
33+
{ text: 'Background Writes', link: '/background-writes' },
3334
{ text: 'Migrations', link: '/migrations' },
3435
{ text: 'Type Checking', link: '/type-check' },
3536
],

docs/background-writes.md

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# Background Writes with `waitUntil`
2+
3+
This guide explains how to perform "fire-and-forget" database operations using Cloudflare's `waitUntil` method. This is particularly useful for tasks that don't need to block the response to the user, such as logging, analytics, or other non-critical writes.
4+
5+
## How it Works
6+
7+
Cloudflare Workers can continue to execute code for a short period after the response has been sent to the client by using the `ctx.waitUntil()` method, where `ctx` is the `ExecutionContext` of your Worker's `fetch` handler.
8+
9+
By wrapping a `workers-qb` query promise in `waitUntil`, you ensure that the query is executed without making the user wait for the database operation to complete.
10+
11+
**Note:** This approach is suitable for operations where you don't need to return the result to the user.
12+
13+
## Examples
14+
15+
Here are some examples of how to use `waitUntil` for different types of write operations.
16+
17+
### Background `insert`
18+
19+
This is useful for logging requests, tracking events, or any other scenario where you need to add a record without delaying the user's response.
20+
21+
```typescript
22+
import { D1QB } from 'workers-qb';
23+
24+
export interface Env {
25+
DB: D1Database;
26+
}
27+
28+
export default {
29+
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
30+
const qb = new D1QB(env.DB);
31+
const url = new URL(request.url);
32+
33+
// Don't await this promise, let it run in the background
34+
const insertPromise = qb.insert({
35+
tableName: 'logs',
36+
data: {
37+
method: request.method,
38+
path: url.pathname,
39+
timestamp: new Date().toISOString(),
40+
},
41+
}).execute();
42+
43+
ctx.waitUntil(insertPromise);
44+
45+
return new Response('Request logged in the background!', { status: 200 });
46+
},
47+
};
48+
```
49+
50+
### Background `update`
51+
52+
You can update records in the background, for example, to increment a counter or update a user's last-seen timestamp.
53+
54+
```typescript
55+
import { D1QB, Raw } from 'workers-qb';
56+
57+
export interface Env {
58+
DB: D1Database;
59+
}
60+
61+
export default {
62+
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
63+
const qb = new D1QB(env.DB);
64+
const userId = request.headers.get('X-User-ID');
65+
66+
if (userId) {
67+
// Don't await this promise
68+
const updatePromise = qb.update({
69+
tableName: 'users',
70+
data: {
71+
last_seen: new Raw('CURRENT_TIMESTAMP'),
72+
},
73+
where: {
74+
conditions: 'id = ?',
75+
params: userId,
76+
},
77+
}).execute();
78+
79+
ctx.waitUntil(updatePromise);
80+
}
81+
82+
return new Response('User activity updated in the background.', { status: 200 });
83+
},
84+
};
85+
```
86+
87+
### Background `delete`
88+
89+
Perform cleanup operations, such as deleting expired sessions or old data, without affecting the response time.
90+
91+
```typescript
92+
import { D1QB } from 'workers-qb';
93+
94+
export interface Env {
95+
DB: D1Database;
96+
}
97+
98+
export default {
99+
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
100+
const qb = new D1QB(env.DB);
101+
const sessionId = request.headers.get('X-Session-ID');
102+
103+
if (sessionId) {
104+
// Don't await this promise
105+
const deletePromise = qb.delete({
106+
tableName: 'sessions',
107+
where: {
108+
conditions: 'id = ?',
109+
params: sessionId,
110+
},
111+
}).execute();
112+
113+
ctx.waitUntil(deletePromise);
114+
}
115+
116+
return new Response('Session invalidated in the background.', { status: 200 });
117+
},
118+
};
119+
```

0 commit comments

Comments
 (0)