Skip to content

Commit 35c522b

Browse files
committed
Removing duplicate demo, using GitHubCode.
1 parent c0003d0 commit 35c522b

File tree

1 file changed

+8
-133
lines changed

1 file changed

+8
-133
lines changed

src/content/docs/d1/best-practices/read-replication.mdx

Lines changed: 8 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -18,138 +18,14 @@ Deploy the following Worker code using Sessions API, which will prompt you to cr
1818

1919
[![Deploy to Cloudflare](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/cloudflare/templates/tree/staging/d1-starter-sessions-api)
2020

21-
```ts collapse={1-6, 34-130}
22-
import { D1Database, D1DatabaseSession } from "@cloudflare/workers-types";
23-
24-
export type Env = {
25-
DB01: D1Database;
26-
};
27-
28-
export default {
29-
async fetch(request, env, ctx): Promise<Response> {
30-
const url = new URL(request.url);
31-
32-
// A. Create the session.
33-
// When we create a D1 session, we can continue where we left off from a previous
34-
// session if we have that session's last bookmark or use a constraint.
35-
const bookmark = request.headers.get('x-d1-bookmark') ?? 'first-unconstrained';
36-
const session = env.DB01.withSession(bookmark);
37-
38-
try {
39-
// Use this session for all our Workers' routes.
40-
const response = await withTablesInitialized(session, async () => await handleRequest(request, session));
41-
42-
// B. Return the bookmark so we can continue the session in another request.
43-
response.headers.set('x-d1-bookmark', session.getBookmark() ?? "");
44-
45-
return response;
46-
47-
} catch (e) {
48-
console.error({ message: "Failed to handle request", error: String(e), errorProps: e, url, bookmark });
49-
return Response.json(
50-
{ error: String(e), errorDetails: e },
51-
{ status: 500 }
52-
);
53-
}
54-
},
55-
} satisfies ExportedHandler<Env>;
56-
57-
type Order = {
58-
orderId: string,
59-
customerId: string,
60-
quantity: number,
61-
}
62-
63-
async function handleRequest(request: Request, session: D1DatabaseSession) {
64-
const { pathname } = new URL(request.url);
65-
66-
const tsStart = Date.now();
67-
68-
if (request.method === "GET" && pathname === '/api/orders') {
69-
// C. session read query.
70-
const resp = await session.prepare('SELECT * FROM Orders').all();
71-
return Response.json(buildResponse(session, resp, tsStart));
72-
73-
} else if (request.method === "POST" && pathname === '/api/orders') {
74-
const order = await request.json<Order>();
75-
76-
// D. session write query.
77-
// Since this is a write query, D1 will transparently forward the query.
78-
await session
79-
.prepare('INSERT INTO Orders VALUES (?, ?, ?)')
80-
.bind(order.customerId, order.orderId, order.quantity)
81-
.run();
82-
83-
// E. session read-after-write query.
84-
// In order for the application to be correct, this SELECT
85-
// statement must see the results of the INSERT statement above.
86-
const resp = await session
87-
.prepare('SELECT * FROM Orders')
88-
.all();
89-
90-
return Response.json(buildResponse(session, resp, tsStart));
91-
92-
} else if (request.method === "POST" && pathname === '/api/reset') {
93-
const resp = await resetTables(session);
94-
95-
return Response.json(buildResponse(session, resp, tsStart));
96-
}
97-
98-
return new Response('Not found', { status: 404 })
99-
}
100-
101-
function buildResponse(session: D1DatabaseSession, res: D1Result, tsStart: number) {
102-
return {
103-
d1Latency: Date.now() - tsStart,
104-
105-
results: res.results,
106-
servedByRegion: res.meta.served_by_region ?? "",
107-
servedByPrimary: res.meta.served_by_primary ?? "",
108-
109-
// Add the session bookmark inside the response body too.
110-
sessionBookmark: session.getBookmark(),
111-
};
112-
}
113-
114-
/**
115-
* This is mostly for DEMO purposes to avoid having to do separate schema migrations step.
116-
* This will check if the error is because our main table is missing, and if it is create the table
117-
* and rerun the handler.
118-
*/
119-
async function withTablesInitialized(session: D1DatabaseSession, handler: () => Promise<Response>) {
120-
try {
121-
return await handler();
122-
} catch (e) {
123-
if (String(e).includes("no such table: Orders: SQLITE_ERROR")) {
124-
await initTables(session);
125-
return await handler();
126-
}
127-
throw e;
128-
}
129-
}
130-
131-
async function initTables(session: D1DatabaseSession) {
132-
return await session
133-
.prepare(`CREATE TABLE IF NOT EXISTS Orders(
134-
customerId TEXT NOT NULL,
135-
orderId TEXT NOT NULL,
136-
quantity INTEGER NOT NULL,
137-
PRIMARY KEY (customerId, orderId)
138-
)`)
139-
.all();
140-
}
141-
142-
async function resetTables(session: D1DatabaseSession) {
143-
return await session
144-
.prepare(`DROP TABLE IF EXISTS Orders; CREATE TABLE IF NOT EXISTS Orders(
145-
customerId TEXT NOT NULL,
146-
orderId TEXT NOT NULL,
147-
quantity INTEGER NOT NULL,
148-
PRIMARY KEY (customerId, orderId)
149-
)`)
150-
.all();
151-
}
152-
```
21+
<GitHubCode
22+
repo="cloudflare/templates"
23+
file="d1-starter-sessions-api/src/index.ts"
24+
commit="3912e863acedd2be2438f8758f21374ed426fc54"
25+
lang="ts"
26+
useTypeScriptExample={true}
27+
lines="7-44"
28+
/>
15329

15430
## Primary database instance vs read replicas
15531

@@ -587,5 +463,4 @@ You may wish to refer to the following resources:
587463
- Blog: [Building D1: a Global Database](https://blog.cloudflare.com/building-d1-a-global-database/)
588464
- [D1 Sessions API documentation](/d1/worker-api/d1-database#withsession)
589465
- [Starter code for D1 Sessions API demo](https://github.com/cloudflare/templates/tree/staging/d1-starter-sessions-api)
590-
- [E-commerce store read replication demo](https://github.com/harshil1712/e-com-d1)
591466
- [E-commerce store read replication tutorial](/d1/tutorials/using-read-replication-for-e-com)

0 commit comments

Comments
 (0)