Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

Durable Objects から Workers KV を使う

Durable Object 内から Workers KV を読み書きします

最終更新 Markdown で表示Agent セットアップ

次の Worker スクリプトは、Durable Object から Workers KV 名前空間 を読み書きする設定方法を示します。複数クライアント間の調整に Durable Object を使う場合に便利です。KV への書き込みを直列化したり、1 回の KV 読み取りを、1 つの Durable Object に WebSockets で 接続した数百〜数千のクライアントへ配信したりできます。

事前準備:

Wrangler ファイルは次のように設定します。

{
	"$schema": "./node_modules/wrangler/config-schema.json",
	"name": "my-worker",
	"main": "src/index.ts",
	"kv_namespaces": [
		{
			"binding": "YOUR_KV_NAMESPACE",
			"id": "<id_of_your_namespace>"
		}
	],
	"durable_objects": {
		"bindings": [
			{
				"name": "YOUR_DO_CLASS",
				"class_name": "YourDurableObject"
			}
		]
	}
}
"$schema" = "./node_modules/wrangler/config-schema.json"
name = "my-worker"
main = "src/index.ts"

[[kv_namespaces]]
binding = "YOUR_KV_NAMESPACE"
id = "<id_of_your_namespace>"

[[durable_objects.bindings]]
name = "YOUR_DO_CLASS"
class_name = "YourDurableObject"
import { DurableObject } from "cloudflare:workers";

interface Env {
	YOUR_KV_NAMESPACE: KVNamespace;
	YOUR_DO_CLASS: DurableObjectNamespace;
}

export default {
	async fetch(req: Request, env: Env): Promise<Response> {
		// Assume each Durable Object is mapped to a roomId in a query parameter
		// In a production application, this will likely be a roomId defined by your application
		// that you validate (and/or authenticate) first.
		let url = new URL(req.url);
		let roomIdParam = url.searchParams.get("roomId");

		if (roomIdParam) {
			// Get a stub that allows you to call that Durable Object
			let durableObjectStub = env.YOUR_DO_CLASS.getByName(roomIdParam);

			// Pass the request to that Durable Object and await the response
			// This invokes the constructor once on your Durable Object class (defined further down)
			// on the first initialization, and the fetch method on each request.
			//
			// You could pass the original Request to the Durable Object's fetch method
			// or a simpler URL with just the roomId.
			let response = await durableObjectStub.fetch(`http://do/${roomId}`);

			// This would return the value you read from KV *within* the Durable Object.
			return response;
		}
	},
};

export class YourDurableObject extends DurableObject {
	constructor(
		public state: DurableObjectState,
		env: Env,
	) {
		super(state, env);
	}

	async fetch(request: Request) {
		// Error handling elided for brevity.
		// Write to KV
		await this.env.YOUR_KV_NAMESPACE.put("some-key");

		// Fetch from KV
		let val = await this.env.YOUR_KV_NAMESPACE.get("some-other-key");

		return Response.json(val);
	}
}
from workers import DurableObject, Response, WorkerEntrypoint
from urllib.parse import urlparse, parse_qs

class Default(WorkerEntrypoint):
	async def fetch(self, req):
		# Assume each Durable Object is mapped to a roomId in a query parameter
		# In a production application, this will likely be a roomId defined by your application
		# that you validate (and/or authenticate) first.
		url = req.url
		parsed_url = urlparse(url)
		room_id_param = parse_qs(parsed_url.query).get('roomId', [None])[0]

		if room_id_param:
			# Get a stub that allows you to call that Durable Object
			durable_object_stub = self.env.YOUR_DO_CLASS.getByName(room_id_param)

			# Pass the request to that Durable Object and await the response
			# This invokes the constructor once on your Durable Object class (defined further down)
			# on the first initialization, and the fetch method on each request.
			#
			# You could pass the original Request to the Durable Object's fetch method
			# or a simpler URL with just the roomId.
			response = await durable_object_stub.fetch(f"http://do/{room_id_param}")

			# This would return the value you read from KV *within* the Durable Object.
			return response

class YourDurableObject(DurableObject):
	def __init__(self, state, env):
		super().__init__(state, env)

	async def fetch(self, request):
		# Error handling elided for brevity.
		# Write to KV
		await self.env.YOUR_KV_NAMESPACE.put("some-key", "some-value")

		# Fetch from KV
		val = await self.env.YOUR_KV_NAMESPACE.get("some-other-key")

		return Response.json(val)

役に立ちましたか?