To get started with Cloudflare Workers and bknd you can either install the package manually, and follow the descriptions below, or use the CLI starter:
If you don't choose anything specific, the following code will use the warm mode and uses the first D1 binding it finds. See the
chapter Using a different mode for available modes.
src/index.ts
import { serve, d1 } from "bknd/adapter/cloudflare";// scans your environment for the first D1 binding it findsexport default serve();// manually specifying a D1 binding:export default serve<Env>({ app: ({ env }) => d1({ binding: env.D1_BINDING }),});// or specify binding using `bindings`export default serve<Env>({ bindings: ({ env }) => ({ db: env.D1_BINDING }),});// or use LibSQLexport default serve<Env>({ app: ({ env }) => ({ url: env.DB_URL }),});
For more information about the connection object when using LibSQL, refer to the Database guide.
Now in order to also server the static admin files, you have to modify the wrangler.toml to include the static assets. You can do so by either serving the static using the new Assets feature, or the deprecated Workers Site.
Since the communication between the Worker and Durable Object is serialized, the onBuilt
property won't work. To use it (e.g. to specify special routes), you need to extend from the
DurableBkndApp:
In case you've already deployed your Worker, the deploy command may complain about a new class
being used. To fix this issue, you need to add a "rename migration":
D1 now supports to enable global read replication. This allows to reduce latency by reading from the closest region. In order for this to work, D1 has to be started from a bookmark. You can enable this behavior on bknd by setting the d1.session property:
src/index.ts
import { serve } from "bknd/adapter/cloudflare";export default serve({ // currently recommended to use "fresh" mode // otherwise consecutive requests will use the same bookmark mode: "fresh", // ... d1: { // enables D1 sessions session: true, // (optional) restrict the transport, options: "header" | "cookie" // if not specified, it supports both transport: "cookie", // (optional) choose session constraint if not bookmark present // options: "first-primary" | "first-unconstrained" first: "first-primary", },});
If bknd is used in a stateful user context (like in a browser), it'll automatically send the session cookie to the server to set the correct bookmark. If you need to manually set the bookmark, you can do so by setting the x-cf-d1-session header: