Skip to content

Use KV from Durable Objects

Read and write to/from KV within a Durable Object

The following Worker script shows you how to configure a Durable Object to read from and/or write to a Workers KV namespace. This is useful when using a Durable Object to coordinate between multiple clients, and allows you to serialize writes to KV and/or broadcast a single read from KV to hundreds or thousands of clients connected to a single Durable Object using WebSockets.

Prerequisites:

Configure your wrangler.toml file as follows:

name = "my-worker"
kv_namespaces = [
{ binding = "YOUR_KV_NAMESPACE", id = "<id_of_your_namespace>" }
]
[durable_objects]
bindings = [
{ name = "YOUR_DO_CLASS", class_name = "YourDurableObject" }
]
import { DurableObject } from 'cloudflare:workers';
interface Env {
YOUR_KV_NAMESPACE: KVNamespace;
YOUR_DO_CLASS: DurableObjectNamespace;
}
export default {
async fetch(req: Request, env: Env): Promise<Response> {
// Assume each Durable Object is mapped to a roomId in a query parameter
// In a production application, this will likely be a roomId defined by your application
// that you validate (and/or authenticate) first.
let url = new URL(req.url);
let roomIdParam = url.searchParams.get("roomId");
if (roomIdParam) {
// Create (or get) a Durable Object based on that roomId.
let durableObjectId = env.YOUR_DO_CLASS.idFromName(roomIdParam);
// Get a "stub" that allows you to call that Durable Object
let durableObjectStub = env.YOUR_DO_CLASS.get(durableObjectId);
// Pass the request to that Durable Object and await the response
// This invokes the constructor once on your Durable Object class (defined further down)
// on the first initialization, and the fetch method on each request.
//
// You could pass the original Request to the Durable Object's fetch method
// or a simpler URL with just the roomId.
let response = await durableObjectStub.fetch(`http://do/${roomId}`);
// This would return the value you read from KV *within* the Durable Object.
return response;
}
}
}
export class YourDurableObject extends DurableObject {
constructor(public state: DurableObjectState, env: Env) {
this.state = state;
// Ensure you pass your bindings and environmental variables into
// each Durable Object when it is initialized
this.env = env;
}
async fetch(request: Request) {
// Error handling elided for brevity.
// Write to KV
await this.env.YOUR_KV_NAMESPACE.put("some-key");
// Fetch from KV
let val = await this.env.YOUR_KV_NAMESPACE.get("some-other-key");
return Response.json(val);
}
}