mcpField
D
durable-objects

durable-objects

github.com/cloudflareクラウド・DevOps3.2k112.9k 回インストール今日更新
リポジトリ

durable-objects について

Cloudflare Durable Objectsによるエッジ上の状態管理と調整を実装・レビューする開発者向けのコーディングスキルです。最新ドキュメントの参照を重視し、ストレージ、並行処理、設定、テストの指針を扱います。

主な機能

  1. 01状態管理と調整の実装ガイド
  2. 02RPC、アラーム、WebSocket
  3. 03Wranglerのバインディングとマイグレーション
  4. 04SQLiteストレージと並行処理の規則
  5. 05Cloudflare Vitestのテストガイド

活用シーン

  1. 01チャットルームやマルチプレイヤー調整の実装
  2. 02Durable Objectコードのレビュー
  3. 03バインディングとマイグレーションの設定
  4. 04Durable Objectのテスト作成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/cloudflare/skills --skill durable-objects

インストール後、Claude Code で/durable-objectsを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
rules.md
testing.md
workers.md

詳細

Durable Objects

Durable Objects を使用して、Cloudflare のエッジ上に状態を保持し、連携するアプリケーションを構築します。

情報の取得元

Durable Objects の API や設定に関する知識は古くなっている可能性があります。Durable Objects に関する作業では、事前学習済みの知識よりも情報の取得を優先してください。

リソースURL
ドキュメントhttps://developers.cloudflare.com/durable-objects/index.md
API リファレンスhttps://developers.cloudflare.com/durable-objects/api/index.md
ベストプラクティスhttps://developers.cloudflare.com/durable-objects/best-practices/index.md
例https://developers.cloudflare.com/durable-objects/examples/index.md
ロールと権限https://developers.cloudflare.com/workers/authorization/durable-objects/index.md

機能を実装するときは、該当するドキュメントページを取得してください。

使用する場面

  • 状態を保持して連携する新しい Durable Object クラスの作成
  • RPC メソッド、アラーム、WebSocket ハンドラーの実装
  • ベストプラクティスに照らした既存の DO コードのレビュー
  • DO バインディングとマイグレーション用の wrangler.jsonc/toml の設定
  • Cloudflare の Vitest 統合を使用したテストの作成
  • シャーディング戦略と親子関係の設計

リファレンスドキュメント

  • ./references/rules.md - 基本ルール、ストレージ、並行処理、RPC、アラーム
  • テストのリファレンス - 最新の Vitest ドキュメント、マイグレーションの選択肢、テストの選び方
  • ./references/workers.md - Workers のハンドラー、型、wrangler 設定、可観測性

検索対象:blockConcurrencyWhile、idFromName、getByName、setAlarm、sql.exec

基本原則

Durable Objects を使用する場面
ニーズ例
連携チャットルーム、マルチプレイヤーゲーム、共同編集ドキュメント
強い一貫性在庫、予約システム、ターン制ゲーム
エンティティごとのストレージマルチテナント SaaS、ユーザーごとのデータ
永続的な接続WebSocket、リアルタイム通知
エンティティごとのスケジュール実行サブスクリプションの更新、ゲームのタイムアウト
使用しない場面
  • ステートレスなリクエスト処理(通常の Workers を使用してください)
  • グローバルに最大限の分散が必要な場合
  • 独立したリクエストを大量にファンアウトする場合

クイックリファレンス

Wrangler の設定
// wrangler.jsonc
{
  "durable_objects": {
    "bindings": [{ "name": "MY_DO", "class_name": "MyDurableObject" }]
  },
  "migrations": [{ "tag": "v1", "new_sqlite_classes": ["MyDurableObject"] }]
}
基本的な Durable Object パターン
import { DurableObject } from "cloudflare:workers";

export interface Env {
  MY_DO: DurableObjectNamespace<MyDurableObject>;
}

export class MyDurableObject extends DurableObject<Env> {
  constructor(ctx: DurableObjectState, env: Env) {
    super(ctx, env);
    ctx.blockConcurrencyWhile(async () => {
      this.ctx.storage.sql.exec(`
        CREATE TABLE IF NOT EXISTS items (
          id INTEGER PRIMARY KEY AUTOINCREMENT,
          data TEXT NOT NULL
        )
      `);
    });
  }

  async addItem(data: string): Promise<number> {
    const result = this.ctx.storage.sql.exec<{ id: number }>(
      "INSERT INTO items (data) VALUES (?) RETURNING id",
      data
    );
    return result.one().id;
  }
}

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const stub = env.MY_DO.getByName("my-instance");
    const id = await stub.addItem("hello");
    return Response.json({ id });
  },
};

重要なルール

  1. 連携の単位を軸にモデル化する - 1 つのグローバル DO ではなく、チャットルーム、ゲーム、ユーザーごとに DO を 1 つ作成します
  2. 決定的なルーティングには getByName() を使用する - 同じ入力は同じ DO インスタンスにルーティングされます
  3. SQLite ストレージを使用する - マイグレーションで new_sqlite_classes を設定します
  4. コンストラクターで初期化する - スキーマのセットアップにのみ blockConcurrencyWhile() を使用します
  5. RPC メソッドを使用する - fetch() ハンドラーは使用しません(互換性日付 >= 2024-04-03)
  6. まず永続化し、その後キャッシュする - インメモリ状態を更新する前に、必ずストレージに書き込みます
  7. DO ごとにアラームは 1 つ - setAlarm() は既存のアラームを置き換えます

認可

Durable Objects に個別のロールや権限はありません。アクセス権は、それらを実装する Worker に従います。可観測性や Data Studio へのアクセス権を付与する前に、最新の Durable Objects の認可ガイダンスを取得し、Workers のロールを対象の Worker または Workers 製品に限定してください。

アンチパターン(絶対に避けること)

  • すべてのリクエストを処理する単一のグローバル DO(ボトルネックになります)
  • リクエストのたびに blockConcurrencyWhile() を使用する(スループットが大幅に低下します)
  • 重要な状態をメモリ内だけに保存する(エビクションやクラッシュ時に失われます)
  • 関連するストレージ書き込みの間に await を使用する(アトミック性が損なわれます)
  • fetch() や外部 I/O の間、blockConcurrencyWhile() を保持する

スタブの作成

// Deterministic - preferred for most cases
const stub = env.MY_DO.getByName("room-123");

// From existing ID string
const id = env.MY_DO.idFromString(storedIdString);
const stub = env.MY_DO.get(id);

// New unique ID - store mapping externally
const id = env.MY_DO.newUniqueId();
const stub = env.MY_DO.get(id);

ストレージ操作

// SQL (synchronous, recommended)
this.ctx.storage.sql.exec("INSERT INTO t (c) VALUES (?)", value);
const rows = this.ctx.storage.sql.exec<Row>("SELECT * FROM t").toArray();

// KV (async)
await this.ctx.storage.put("key", value);
const val = await this.ctx.storage.get<Type>("key");

アラーム

// Schedule (replaces existing)
await this.ctx.storage.setAlarm(Date.now() + 60_000);

// Handler
async alarm(): Promise<void> {
  // Process scheduled work
  // Optionally reschedule: await this.ctx.storage.setAlarm(...)
}

// Cancel
await this.ctx.storage.deleteAlarm();

テスト

テストスイートを設定したり Durable Object のテストを作成したりする前に、テストのリファレンスをお読みください。最新のセットアップ方法、API、例に加え、テスト対象にすべき動作を確認できます。

コメント