Skip to content

Commit 145e28e

Browse files
authored
WIP for code example
1 parent 1e31b7b commit 145e28e

File tree

1 file changed

+117
-0
lines changed

1 file changed

+117
-0
lines changed

src/content/docs/workers/examples/cache-post-request.mdx

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ description: Cache POST requests using the Cache API.
1717

1818
import { TabItem, Tabs } from "~/components";
1919

20+
POST requests can be cached either via Cache API or [Workers KV](/kv/).
21+
22+
## Using Cache API
23+
24+
The Cache API allows for a simple API to cache POST requests. However, Cache API does not [support the use of Tiered Caching or Reserve Reserve](/workers/reference/how-the-cache-works/#cache-api). To increase Cache Hit Rates and offload origin load, consider using Workers KV instead (see below).
25+
2026
<Tabs syncKey="workersExamples"> <TabItem label="JavaScript" icon="seti:javascript">
2127

2228
```js
@@ -148,3 +154,114 @@ async def on_fetch(request, _, ctx):
148154
```
149155

150156
</TabItem> </Tabs>
157+
158+
159+
## Using Workers KV
160+
161+
KV allows
162+
163+
<Tabs syncKey="workersExamples"> <TabItem label="JavaScript" icon="seti:javascript">
164+
165+
```js
166+
167+
const serializeResponse() = () => {
168+
// TODO: Implement Request -> JSON/Text
169+
}
170+
171+
const deserializeResponse() = () => {
172+
// TODO: Implement JSON/Text -> Request
173+
}
174+
175+
export default {
176+
async fetch(request, env, ctx) {
177+
async function sha256(message) {
178+
// encode as UTF-8
179+
const msgBuffer = await new TextEncoder().encode(message);
180+
// hash the message
181+
const hashBuffer = await crypto.subtle.digest("SHA-256", msgBuffer);
182+
// convert bytes to hex string
183+
return [...new Uint8Array(hashBuffer)]
184+
.map((b) => b.toString(16).padStart(2, "0"))
185+
.join("");
186+
}
187+
try {
188+
if (request.method.toUpperCase() === "POST") {
189+
const body = await request.clone().text();
190+
// Hash the request body to use it as a part of the cache key
191+
const hash = await sha256(body);
192+
const cacheUrl = new URL(request.url);
193+
// Store the URL in cache by prepending the body's hash
194+
cacheUrl.pathname = "/posts" + cacheUrl.pathname + hash;
195+
// Convert to a GET to be able to cache
196+
const cacheKey = new Request(cacheUrl.toString(), {
197+
headers: request.headers,
198+
method: "GET",
199+
});
200+
201+
// Find the cache key in KV
202+
let response = deserializeResponse(await env.KV.get());
203+
// Otherwise, fetch response to POST request from origin
204+
if (!response) {
205+
response = await fetch(request);
206+
// TODO: Add expiry
207+
ctx.waitUntil(env.KV.put(cacheKey, serializeResponse()));
208+
}
209+
return response;
210+
}
211+
return fetch(request);
212+
} catch (e) {
213+
return new Response("Error thrown " + e.message);
214+
}
215+
},
216+
};
217+
```
218+
219+
</TabItem> <TabItem label="TypeScript" icon="seti:typescript">
220+
221+
```ts
222+
interface Env {}
223+
export default {
224+
async fetch(request, env, ctx): Promise<Response> {
225+
async function sha256(message) {
226+
// encode as UTF-8
227+
const msgBuffer = await new TextEncoder().encode(message);
228+
// hash the message
229+
const hashBuffer = await crypto.subtle.digest("SHA-256", msgBuffer);
230+
// convert bytes to hex string
231+
return [...new Uint8Array(hashBuffer)]
232+
.map((b) => b.toString(16).padStart(2, "0"))
233+
.join("");
234+
}
235+
try {
236+
if (request.method.toUpperCase() === "POST") {
237+
const body = await request.clone().text();
238+
// Hash the request body to use it as a part of the cache key
239+
const hash = await sha256(body);
240+
const cacheUrl = new URL(request.url);
241+
// Store the URL in cache by prepending the body's hash
242+
cacheUrl.pathname = "/posts" + cacheUrl.pathname + hash;
243+
// Convert to a GET to be able to cache
244+
const cacheKey = new Request(cacheUrl.toString(), {
245+
headers: request.headers,
246+
method: "GET",
247+
});
248+
249+
const cache = caches.default;
250+
// Find the cache key in the cache
251+
let response = await cache.match(cacheKey);
252+
// Otherwise, fetch response to POST request from origin
253+
if (!response) {
254+
response = await fetch(request);
255+
ctx.waitUntil(cache.put(cacheKey, response.clone()));
256+
}
257+
return response;
258+
}
259+
return fetch(request);
260+
} catch (e) {
261+
return new Response("Error thrown " + e.message);
262+
}
263+
},
264+
} satisfies ExportedHandler<Env>;
265+
```
266+
267+
</TabItem></Tabs>

0 commit comments

Comments
 (0)