Cloudflare Durable Objects
Cloudflare Durable Objects können HTTP-Anfragen nicht direkt verarbeiten. Stattdessen erfolgt die Verarbeitung in einem zweistufigen Ablauf:
- Ein Worker empfängt HTTP-Fetch-Anfragen von Clients
- Der Worker führt RPC-Aufrufe (Remote Procedure Calls) am Durable Object aus
- Das Durable Object verarbeitet den RPC-Aufruf und gibt das Ergebnis an den Worker zurück
- 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 appwrangler.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.