# Worker

import { Steps } from '@astrojs/starlight/components';

This guide walks you through creating, testing, and deploying a Cloudflare Worker, then evolving it to use Durable Objects for session storage.

:::note
For a complete Worker API reference, see the [Worker Provider](/providers/cloudflare/worker) documentation.
:::

<Steps>

1. **Create a Worker**

   Start by defining a Worker in your `alchemy.run.ts` file.

   ```ts
   import alchemy from "alchemy";
   import { Worker } from "alchemy/cloudflare";

   const app = await alchemy("my-app");

   export const worker = await Worker("api", {
     entrypoint: "./src/worker.ts",
     url: true, // Get a public URL
   });

   console.log({ url: worker.url });
   await app.finalize();
   ```

2. **Implement the Worker**

   Create your Worker script with a basic fetch handler.

   ```ts title="src/worker.ts"
   import type { worker } from "../alchemy.run";

   export default {
     async fetch(request: Request, env: typeof worker.Env): Promise<Response> {
       const url = new URL(request.url);
       
       return Response.json({
         message: "Hello from Alchemy!",
         path: url.pathname,
       });
     },
   };
   ```

3. **Test Locally**

   Run the Worker in development mode.

   ```bash
   bun alchemy dev
   ```

   Your Worker is now running locally and will auto-reload on code changes.

4. **Deploy to Production**

   Deploy your Worker to Cloudflare's edge network.

   ```bash
   bun alchemy deploy
   ```

   Your Worker is now live at the URL shown in the console.

5. **Add Session Storage**

   Create a [Durable Object namespace](/providers/cloudflare/durable-object-namespace) to store session data.

   ```diff lang="ts" title="alchemy.run.ts"
    import alchemy from "alchemy";
   -import { Worker } from "alchemy/cloudflare";
   +import { Worker, DurableObjectNamespace } from "alchemy/cloudflare";

    const app = await alchemy("my-app");

   +const sessions = DurableObjectNamespace("sessions", {
   +  className: "Session",
   +  sqlite: true,
   +});
   +
    export const worker = await Worker("api", {
      entrypoint: "./src/worker.ts",
      url: true,
   +  bindings: {
   +    SESSIONS: sessions,
   +  },
    });

    console.log({ url: worker.url });
    await app.finalize();
   ```

6. **Implement the Session Class**

   Create a Durable Object to handle session state.

   ```ts title="src/worker.ts"
   import { DurableObject } from "cloudflare:workers";
   import type { worker } from "../alchemy.run";

   export class Session extends DurableObject {
     async fetch(request: Request) {
       const url = new URL(request.url);
       
       if (url.pathname === "/set") {
         const data = await request.json();
         await this.ctx.storage.put("data", data);
         return Response.json({ success: true });
       }
       
       const data = await this.ctx.storage.get("data");
       return Response.json({ data });
     }
   }
   ```

   :::tip
   See the [Durable Objects guide](/guides/cloudflare-durable-objects) for more details on implementing Durable Objects and Cloudflare's [Durable Objects documentation](https://developers.cloudflare.com/durable-objects/get-started/).
   :::

7. **Use Session from Worker**

   Update your Worker to use sessions based on a request header.

   ```diff lang="ts" title="src/worker.ts"
   +import { env } from "cloudflare:workers";
    import type { worker } from "../alchemy.run";

    export default {
      async fetch(request: Request, env: typeof worker.Env): Promise<Response> {
   -    const url = new URL(request.url);
   -    
   -    return Response.json({
   -      message: "Hello from Alchemy!",
   -      path: url.pathname,
   -    });
   +    const sessionId = request.headers.get("x-session-id") || "default";
   +    
   +    // Get the session Durable Object
   +    const id = env.SESSIONS.idFromName(sessionId);
   +    const session = env.SESSIONS.get(id);
   +    
   +    // Forward request to session
   +    return session.fetch(request);
      },
    };
   ```

8. **Test the Session**

   Test your session-enabled Worker locally.

   ```bash
   # Set session data
   curl -X POST http://localhost:8787/set \
     -H "x-session-id: user-123" \
     -H "Content-Type: application/json" \
     -d '{"name": "Alice", "theme": "dark"}'

   # Get session data
   curl http://localhost:8787 \
     -H "x-session-id: user-123"
   ```

9. **Deploy Updated Worker**

   Deploy your session-enabled Worker to production.

   ```bash
   bun alchemy deploy
   ```

   Your Worker now persists session data across requests using Durable Objects.

</Steps>

:::tip
For more advanced patterns, see the [Durable Objects guide](/guides/cloudflare-durable-objects) and [Cloudflare's Worker documentation](https://developers.cloudflare.com/workers/).
:::