The following Worker script shows you how to configure a Durable Object to read from and/or write to a [Workers KV namespace](https://developers.cloudflare.com/kv/concepts/how-kv-works/). 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](https://developers.cloudflare.com/durable-objects/best-practices/websockets/).

Prerequisites:

* A [KV namespace](https://developers.cloudflare.com/kv/api/) created via the Cloudflare dashboard or the [wrangler CLI](https://developers.cloudflare.com/workers/wrangler/install-and-update/).
* A [configured binding](https://developers.cloudflare.com/kv/concepts/kv-bindings/) for the `kv_namespace` in the Cloudflare dashboard or Wrangler file.
* A [Durable Object namespace binding](https://developers.cloudflare.com/workers/wrangler/configuration/#durable-objects).

Configure your Wrangler file as follows:

* wrangler.jsonc

  ```jsonc
  {
    "name": "my-worker",
    "kv_namespaces": [
      {
        "binding": "YOUR_KV_NAMESPACE",
        "id": "<id_of_your_namespace>"
      }
    ],
    "durable_objects": {
      "bindings": [
        {
          "name": "YOUR_DO_CLASS",
          "class_name": "YourDurableObject"
        }
      ]
    }
  }
  ```

* wrangler.toml

  ```toml
  name = "my-worker"


  kv_namespaces = [
    { binding = "YOUR_KV_NAMESPACE", id = "<id_of_your_namespace>" }
  ]


  [durable_objects]
  bindings = [
    { name = "YOUR_DO_CLASS", class_name = "YourDurableObject" }
  ]
  ```

```ts
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);
  }
}
```
