カウンターを構築する
Durable ObjectsとWorkersを使用してRPCメソッドでカウンターを構築します。
この例では、URLのクエリ文字列パラメータで提供されたnameを印刷、インクリメント、デクリメントできるカウンターを、RPCメソッドを使用してDurable ObjectsとWorkersで構築する方法を示します。例えば、?name=Aのように指定します。
import { DurableObject } from "cloudflare:workers";
// Workerexport default { async fetch(request, env) { let url = new URL(request.url); let name = url.searchParams.get("name"); if (!name) { return new Response( "Durable Objectに連絡するには、" + " `name` URLクエリ文字列パラメータを使用してください。例えば、?name=A" ); }
// ユニークなIDは、独自の状態を持つCounterクラスの個々のインスタンスを指します。 // `idFromName()`は、同じ文字列を入力として与えられた場合、常に同じIDを返します(同じクラスで呼び出された場合)。 // しかし、異なる2つの文字列(または異なるクラス)に対しては、決して同じIDを返しません。 let id = env.COUNTERS.idFromName(name);
// IDを使用してDurable Objectのスタブを構築します。 // スタブは、Durable Objectにメッセージを送信するために使用されるクライアントオブジェクトです。 let stub = env.COUNTERS.get(id);
// Durable ObjectにRPCメソッドを使用してリクエストを送信し、その応答を待ちます。 let count = null; switch (url.pathname) { case "/increment": count = await stub.increment(); break; case "/decrement": count = await stub.decrement(); break; case "/": // 現在の値を提供します。 count = await stub.getCounterValue(); break; default: return new Response("見つかりません", { status: 404 }); }
return new Response(`Durable Object '${name}' のカウント: ${count}`); }};
// Durable Objectexport class Counter extends DurableObject {
async getCounterValue() { let value = (await this.ctx.storage.get("value")) || 0; return value; }
async increment(amount = 1) { let value = (await this.ctx.storage.get("value")) || 0; value += amount; // ストレージ内の値が同時リクエストによって変更されることを心配する必要はありません。 // "input gates"は自動的に不要な同時実行を防ぎます。 // 読み取り-変更-書き込みは安全です。 await this.ctx.storage.put("value", value); return value; }
async decrement(amount = 1) { let value = (await this.ctx.storage.get("value")) || 0; value -= amount; await this.ctx.storage.put("value", value); return value; }}import { DurableObject } from "cloudflare:workers";
export interface Env { COUNTERS: DurableObjectNamespace<Counter>;}
// Workerexport default { async fetch(request, env) { let url = new URL(request.url); let name = url.searchParams.get("name"); if (!name) { return new Response( "Durable Objectに連絡するには、" + " `name` URLクエリ文字列パラメータを使用してください。例えば、?name=A" ); }
// ユニークなIDは、独自の状態を持つCounterクラスの個々のインスタンスを指します。 // `idFromName()`は、同じ文字列を入力として与えられた場合、常に同じIDを返します(同じクラスで呼び出された場合)。 // しかし、異なる2つの文字列(または異なるクラス)に対しては、決して同じIDを返しません。 let id = env.COUNTERS.idFromName(name);
// IDを使用してDurable Objectのスタブを構築します。 // スタブは、Durable Objectにメッセージを送信するために使用されるクライアントオブジェクトです。 let stub = env.COUNTERS.get(id);
let count = null; switch (url.pathname) { case "/increment": count = await stub.increment(); break; case "/decrement": count = await stub.decrement(); break; case "/": // 現在の値を提供します。 count = await stub.getCounterValue(); break; default: return new Response("見つかりません", { status: 404 }); }
return new Response(`Durable Object '${name}' のカウント: ${count}`); }} satisfies ExportedHandler<Env>;
// Durable Objectexport class Counter extends DurableObject {
async getCounterValue() { let value = (await this.ctx.storage.get("value")) || 0; return value; }
async increment(amount = 1) { let value: number = (await this.ctx.storage.get("value")) || 0; value += amount; // ストレージ内の値が同時リクエストによって変更されることを心配する必要はありません。 // "input gates"は自動的に不要な同時実行を防ぎます。 // 読み取り-変更-書き込みは安全です。 await this.ctx.storage.put("value", value); return value; }
async decrement(amount = 1) { let value: number = (await this.ctx.storage.get("value")) || 0; value -= amount; await this.ctx.storage.put("value", value); return value; }}最後に、wrangler.tomlファイルを構成して、以前に選択した名前空間とクラス名に基づいてDurable Objectのバインディングとマイグレーションを含めます。
name = "my-counter"
[[durable_objects.bindings]]name = "COUNTERS"class_name = "Counter"
[[migrations]]tag = "v1"new_classes = ["Counter"]