Aller au contenu

Cloudflare Durable Objects ​

Les Durable Objects de Cloudflare ne traitent pas directement les requêtes HTTP. Ils fonctionnent plutôt selon un processus en deux étapes principales :

  1. Un Worker reçoit les requêtes HTTP fetch des clients
  2. Le Worker effectue des appels RPC (appels de procédure distante) vers le Durable Object
  3. Le Durable Object traite l’appel RPC et renvoie le résultat au Worker
  4. Le Worker renvoie la réponse HTTP au client

Vous pouvez utiliser Hono comme routeur dans votre Cloudflare Worker et effectuer des appels RPC (appels de procédure distante) pour interagir avec les Durable Objects. Il s’agit de l’approche recommandée à partir de la date de compatibilité Cloudflare Workers 2024-04-03.

Exemple : un Durable Object compteur ​

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,
  },
}

Vous disposez maintenant d’une application Hono pleinement fonctionnelle qui communique avec votre Durable Object ! Le routeur Hono fournit une interface d’API claire pour interagir avec les méthodes du Durable Object et les exposer.

Publié sous licence MIT.