Skip to content

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

Context (ctx)

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

Context API は、Worker または Durable Object のライフサイクルを管理するメソッドを提供します。

Context は次の場所から使えます。

Context API が使えるのはステートレスなコンテキストだけです。つまり Durable Objects では使えません。ただし Durable Objects には別のオブジェクト Durable Object State があり、Durable Object クラス内では this.ctx として使えます。Context API の一部と同じ機能を提供します。

props

ctx.props は、呼び出された文脈に応じて、Worker へ追加の設定を渡す手段です。たとえば、別の Worker から呼ばれたとき、ctx.props で呼び出し元の情報を渡せます。

たとえば、"frontend-worker" という Worker が、文書を操作するために "doc-worker" とやり取りする必要があるとします。"frontend-worker" には、次のような Service Binding を設定できます。

{
	"services": [
		{
			"binding": "DOC_SERVICE",
			"service": "doc-worker",
			"entrypoint": "DocServiceApi",
			"props": {
				"clientId": "frontend-worker",
				"permissions": [
					"read",
					"write"
				]
			}
		}
	]
}
[[services]]
binding = "DOC_SERVICE"
service = "doc-worker"
entrypoint = "DocServiceApi"

  [services.props]
  clientId = "frontend-worker"
  permissions = [ "read", "write" ]

これで frontend-worker は、env.DOC_SERVICE.getDoc(id) のように doc-worker を呼べます。これは Remote Procedure Call になり、doc-worker がエクスポートする WorkerEntrypoint クラス DocServiceApigetDoc() メソッドを呼び出します。

設定には props 値があります。任意の JSON 値です。DOC_SERVICE バインディングが使われると、呼び出しを受ける DocServiceApi インスタンスは、この props 値を this.ctx.props として参照できます。ここでは、呼び出し元が frontend-worker であること、および文書の読み書きが許可されることを props で指定しています。props の内容は自由に決められます。

Workers プラットフォームは、ctx.props を設定できるのが、その値を受け取る Worker を編集・デプロイする権限を持つ者だけになるよう設計されています。そのため、ctx.props の内容は本物だと信頼できます。ctx.props の値に秘密鍵や暗号署名を使う必要はありません。

ctx.props は、RPC インターフェイスを 特定の リソース向けに設定し、「カスタムバインディング」を作るためにも使えます。たとえば、特定の文書だけにアクセスを許可する Service Binding を "doc-worker" 向けに設定できます。

{
	"services": [
		{
			"binding": "FOO_DOCUMENT",
			"service": "doc-worker",
			"entrypoint": "DocumentApi",
			"props": {
				"docId": "e366592caec1d88dff724f74136b58b5",
				"permissions": [
					"read",
					"write"
				]
			}
		}
	]
}
[[services]]
binding = "FOO_DOCUMENT"
service = "doc-worker"
entrypoint = "DocumentApi"

  [services.props]
  docId = "e366592caec1d88dff724f74136b58b5"
  permissions = [ "read", "write" ]

ここでは ctx.propsdocId プロパティを置いています。DocumentApi クラスは、ctx.props.docId で識別される特定の文書向けの API を提供し、指定された権限を強制するように設計できます。

exports

ctx.exports は、トップレベルのエクスポートすべてに対して、自動設定された「ループバック」バインディングを提供します。

  • extends WorkerEntrypoint のトップレベルエクスポート(または単に fetch ハンドラーを実装するもの)ごとに、ctx.exports には Service Binding が自動的に入ります。
  • extends DurableObject のトップレベルエクスポート(かつ マイグレーション でストレージが設定されているもの)ごとに、ctx.exports には Durable Object 名前空間バインディング が自動的に入ります。

例:

import { WorkerEntrypoint } from "cloudflare:workers";

export class Greeter extends WorkerEntrypoint {
	greet(name) {
		return `Hello, ${name}!`;
	}
}

export default {
	async fetch(request, env, ctx) {
		let greeting = await ctx.exports.Greeter.greet("World");
		return new Response(greeting);
	},
};

この例では、デフォルトの fetch ハンドラーが Service Binding と同じように、RPC 経由で Greeter クラスを呼び出します。外部設定は不要です。ctx.exports はトップレベルのエクスポートから 自動的に 埋まります。

ctx.exports 利用時に ctx.props を指定する

ctx.exports 内のループバック Service Bindings には、通常の Service Bindings にない追加機能があります。呼び出し側が、呼び出し先へ渡す ctx.props の値を指定できます。

import { WorkerEntrypoint } from "cloudflare:workers";

export class Greeter extends WorkerEntrypoint {
	greet(name) {
		return `${this.ctx.props.greeting}, ${name}!`;
	}
}

export default {
	async fetch(request, env, ctx) {
		// Make a custom greeter that uses the greeting "Welcome".
		let greeter = ctx.exports.Greeter({ props: { greeting: "Welcome" } });

		// Greet the world. Returns "Welcome, World!"
		let greeting = await greeter.greet("World");

		return new Response(greeting);
	},
};
import { WorkerEntrypoint } from "cloudflare:workers";

type Props = {
	greeting: string;
};

export class Greeter extends WorkerEntrypoint<Env, Props> {
	greet(name) {
		return `${this.ctx.props.greeting}, ${name}!`;
	}
}

export default {
	async fetch(request, env, ctx) {
		// Make a custom greeter that uses the greeting "Welcome".
		let greeter = ctx.exports.Greeter({ props: { greeting: "Welcome" } });

		// Greet the world. Returns "Welcome, World!"
		let greeting = await greeter.greet("World");

		return new Response(greeting);
	},
} satisfies ExportedHandler<Env>;

この場合に props を動的に指定できるのは、呼び出し側が同じ Worker であり、任意の props を指定しても信頼できるとみなせるためです。props をカスタマイズできることは、できたバインディングを RPC 経由で別の Worker に渡すときや、動的に読み込む Workerenv で使うときに特に便利です。

この方法で指定する props 値には、「永続的に」シリアライズ可能な任意の型を入れられます。基本的な 構造化クローン可能なデータ型 はすべて含まれます。Service Bindings 自体も含まれます。ある Service Binding の props に、別の Service Binding を置けます。

ctx.exportsctx.props の TypeScript 型

TypeScript を使う場合は、wrangler types コマンド でプロジェクトの型を自動生成してください。生成された型により、ctx.exports が正しく型付けされます。

props を受け取るエントリポイントクラスを宣言するときは、extends WorkerEntrypoint<Env, Props> としてください。Propsctx.props の型です。上の例を参照してください。

tracing

ctx.tracing は、ユーザー定義のトレーススパンを作る カスタムスパン API へのアクセスを提供します。import { tracing } from "cloudflare:workers" で得られるオブジェクトと同じです。

スパンを記録するには、Worker で トレーシングを有効 にする必要があります。

export default {
	async fetch(request, env, ctx) {
		return ctx.tracing.enterSpan("handleRequest", async (span) => {
			span.setAttribute("url.path", new URL(request.url).pathname);
			const data = await env.MY_KV.get("key");
			return new Response(data);
		});
	},
};

API の詳細は カスタムスパン を参照してください。

waitUntil

ctx.waitUntil() は Worker の生存期間を延ばし、レスポンス返却をブロックせずに処理を実行できます。レスポンス返却後も処理を続けられます。引数は Promise で、Worker の ハンドラー がレスポンスを返したあとも、Workers ランタイムはその Promise の実行を続けます。

レスポンス送信後に実行できる処理(ログ、分析、キャッシュ書き込みなど)で、waitUntil() の制限時間内に終わるものに ctx.waitUntil() を使います。クライアントがレスポンス(ストリーミング本文を含む)を受信中なら、ctx.waitUntil() なしでも Worker の呼び出しはアクティブなままです。レスポンスがその処理に依存する場合は、返す前に await するか、処理の完了に合わせてレスポンスをストリーミングしてください。

waitUntil の一般的な用途は次のとおりです。

  • 外部の分析プロバイダーへイベントを送る(Workers Analytics Engine を使う場合は waitUntil は不要です)
  • Cache API でキャッシュにアイテムを入れる

waitUntil() は複数回呼べます。Promise.allSettled と同様に、ある waitUntil に渡した Promise が拒否されても、ほかの waitUntil() に渡した Promise は実行を続けます。

例:

export default {
	async fetch(request, env, ctx) {
		// Forward / proxy original request
		let res = await fetch(request);

		// Add custom header(s)
		res = new Response(res.body, res);
		res.headers.set("x-foo", "bar");

		// Cache the response
		// NOTE: Does NOT block / wait
		ctx.waitUntil(caches.default.put(request, res.clone()));

		// Done
		return res;
	},
};

passThroughOnException

passThroughOnException メソッドを使うと、Worker は フェイルオープン し、未処理の例外が投げられたときにリクエストをオリジンサーバーへ通せます。既存サービスの前段として Workers を使う場合に便利です。Worker 内で想定外のエラーが起きても、背後のサービスに処理を任せられます。

export default {
	async fetch(request, env, ctx) {
		ctx.passThroughOnException();

		try {
			return await fetch(request);
		} catch (error) {
			console.error("Origin fetch failed", error);
			return new Response("Bad Gateway", { status: 502 });
		}
	},
};

役に立ちましたか?