Skip to content

Instantly share code, notes, and snippets.

@lukeed
Last active May 13, 2021 20:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lukeed/308954a387c071a42a793074777542fd to your computer and use it in GitHub Desktop.
Save lukeed/308954a387c071a42a793074777542fd to your computer and use it in GitHub Desktop.
Demo showing how to integrate with the Cache API and then use custom KV lookup mechanics
import { Router } from 'worktop';
import * as Cache from 'worktop/cache';
import { read, write } from 'worktop/kv';
import type { Method } from 'worktop/request';
import type { Handler } from 'worktop';
import type { KV } from 'worktop/kv';
// KV Namespace Binding
declare const SAVED: KV.Namespace;
const API = new Router;
interface Head {
status: number;
headers: Record<string, string>;
}
// Custom utility method
// Write the generated `Response` into KV
const persist: Handler = async function (req, res) {
await write<Head>(SAVED, `${req.method}::${req.url}::head`, {
headers: res.getHeaders(),
status: res.status,
});
if (!isBodyless(req.method, res.status)) {
await write(SAVED, `${req.method}::${req.url}::body`, res.body);
}
}
function isBodyless(method: Method, status: number) {
return (method === 'HEAD' || status === 101 || status === 204 || status === 205 || status === 304);
}
// Cache MISS, so check KV now
// NOTE: Runs before any (and all) routing
API.prepare = async function (req, res) {
let head = await read<Head>(SAVED, `${req.method}::${req.url}::head`, 'json');
if (!head) return; // stop here, had no match
let { status, headers } = head;
let body = isBodyless(req.method, status) ? null
: await read<ArrayBuffer>(SAVED, `${req.method}::${req.url}::body`, 'arrayBuffer');
return new Response(body, { status, headers });
}
// Every/Any route handler
// Cache MISS && KV does not exist
API.add('GET', '/foo/:name', async (req, res) => {
let data = await fetch('...something...');
res.setHeader('Cache-Control', 'public,max-age=3600');
res.body = await data.text();
res.status = 201;
return persist(req, res);
});
// Every/Any route handler
// Cache MISS && KV does not exist
API.add('GET', '/hello/:world', (req, res) => {
// NOTE: Can still use response helpers
res.send(201, `hello, ${req.params.world}`)
// ~> just send everything thru persist
return persist(req, res);
});
// Init & hookup to Cache API
Cache.listen(API.run);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment