Zum Inhalt springen

Cloudflare Durable Objects ​

Cloudflare Durable Objects können HTTP-Anfragen nicht direkt verarbeiten. Stattdessen erfolgt die Verarbeitung in einem zweistufigen Ablauf:

  1. Ein Worker empfängt HTTP-Fetch-Anfragen von Clients
  2. Der Worker führt RPC-Aufrufe (Remote Procedure Calls) am Durable Object aus
  3. Das Durable Object verarbeitet den RPC-Aufruf und gibt das Ergebnis an den Worker zurück
  4. Der Worker sendet die HTTP-Antwort an den Client

Du kannst Hono als Router in deinem Cloudflare Worker verwenden und über RPC-Aufrufe (Remote Procedure Calls) mit Durable Objects interagieren. Ab dem Cloudflare-Workers-Kompatibilitätsdatum 2024-04-03 ist dies die empfohlene Vorgehensweise.

Beispiel: Zähler als Durable Object ​

ts
import { DurableObject } from 'cloudflare:workers'
import { Hono } from 'hono'

export class Counter extends DurableObject {
  // In-memory state
  value = 0

  constructor(ctx: DurableObjectState, env: unknown) {
    super(ctx, env)

    // `blockConcurrencyWhile()` ensures no requests are delivered until initialization completes.
    ctx.blockConcurrencyWhile(async () => {
      // After initialization, future reads do not need to access storage.
      this.value = (await ctx.storage.get('value')) || 0
    })
  }

  async getCounterValue() {
    return this.value
  }

  async increment(amount = 1): Promise<number> {
    this.value += amount
    await this.ctx.storage.put('value', this.value)
    return this.value
  }

  async decrement(amount = 1): Promise<number> {
    this.value -= amount
    await this.ctx.storage.put('value', this.value)
    return this.value
  }
}

// Create a new Hono app to handle incoming HTTP requests
type Bindings = {
  COUNTER: DurableObjectNamespace<Counter>
}

const app = new Hono<{ Bindings: Bindings }>()

// Add routes to interact with the Durable Object
app.get('/counter', async (c) => {
  const env = c.env
  const id = env.COUNTER.idFromName('counter')
  const stub = env.COUNTER.get(id)
  const counterValue = await stub.getCounterValue()
  return c.text(counterValue.toString())
})

app.post('/counter/increment', async (c) => {
  const env = c.env
  const id = env.COUNTER.idFromName('counter')
  const stub = env.COUNTER.get(id)
  const value = await stub.increment()
  return c.text(value.toString())
})

app.post('/counter/decrement', async (c) => {
  const env = c.env
  const id = env.COUNTER.idFromName('counter')
  const stub = env.COUNTER.get(id)
  const value = await stub.decrement()
  return c.text(value.toString())
})

// Export the Hono app as the Worker's fetch handler
export default app

wrangler.jsonc:

jsonc
{
  "$schema": "node_modules/wrangler/config-schema.json",
  "name": "durable",
  "main": "src/index.ts",
  "compatibility_date": "2025-04-14",
  "migrations": [
    {
      "new_sqlite_classes": ["Counter"],
      "tag": "v1",
    },
  ],
  "durable_objects": {
    "bindings": [
      {
        "class_name": "Counter",
        "name": "COUNTER",
      },
    ],
  },
  "observability": {
    "enabled": true,
  },
}

Jetzt hast du eine vollständig funktionsfähige Hono-Anwendung, die mit deinem Durable Object kommuniziert! Der Hono-Router bietet eine übersichtliche API-Schnittstelle, um die Methoden deines Durable Objects aufzurufen und nach außen bereitzustellen.

Veröffentlicht unter der MIT-Lizenz.