跳转到内容
本站为社区维护的非官方中文翻译,与 Cloudflare, Inc. 无关联。本站不提供账户登录,请勿在任何非官方站点输入您的 Cloudflare 账户信息。官方文档:developers.cloudflare.com

路由选项

最后更新 查看 MarkdownAgent 设置

将选项作为第三个参数传给 routeAgentRequest()。选项类型为从 agents/routing 导出的 AgentOptions:

选项 类型 说明
prefix string 绑定名称和对象名称之前的 URL 路径段。默认为 agents。
cors boolean | HeadersInit 为匹配的响应添加 CORS 标头,并响应匹配的 OPTIONS 预检请求。
jurisdiction DurableObjectJurisdiction 在辖区(例如 "eu")中创建对象。
locationHint DurableObjectLocationHint 提示对象创建位置,例如 "enam"。
props object 当请求启动对象时,传递给 onStart(props) 的 JSON 可序列化值。
routingRetry false | RoutingRetryOptions 重试 Durable Object 的瞬时错误。默认启用。
onBeforeConnect (request, route) => Response | Request | void 转发 WebSocket 升级之前,在 Worker 中运行。
onBeforeRequest (request, route) => Response | Request | void 转发 HTTP 请求之前,在 Worker 中运行。

onBeforeConnect 和 onBeforeRequest 的说明请参阅身份验证。

前缀

prefix 会替换 agents 路径段。它可以包含多个路径段:

import { routeAgentRequest } from "agents/routing";

export default {
	async fetch(request, env) {
		// Matches /api/v1/my-agent/alice
		return (
			(await routeAgentRequest(request, env, { prefix: "api/v1" })) ??
			new Response("Not found", { status: 404 })
		);
	},
};
import { routeAgentRequest } from "agents/routing";

export default {
	async fetch(request: Request, env: Env): Promise<Response> {
		// Matches /api/v1/my-agent/alice
		return (
			(await routeAgentRequest(request, env, { prefix: "api/v1" })) ??
			new Response("Not found", { status: 404 })
		);
	},
} satisfies ExportedHandler<Env>;

useAgent 和 AgentClient 会构建 /agents/... 路径。使用其他前缀时,请将完整路径传给它们的 basePath 选项,例如 basePath: "api/v1/my-agent/alice"。

CORS

当前端运行在其他源时,请设置 cors: true。它会为每个匹配的 HTTP 响应添加以下标头:

  • Access-Control-Allow-Origin: *
  • Access-Control-Allow-Methods: GET, POST, HEAD, OPTIONS
  • Access-Control-Allow-Headers: *
  • Access-Control-Max-Age: 86400

对于携带凭据的请求,请传入包含特定源的自定义标头:

import { routeAgentRequest } from "agents/routing";

export default {
	async fetch(request, env) {
		return (
			(await routeAgentRequest(request, env, {
				cors: {
					"Access-Control-Allow-Origin": "https://app.example.com",
					"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
					"Access-Control-Allow-Headers": "Content-Type, Authorization",
					"Access-Control-Allow-Credentials": "true",
				},
			})) ?? new Response("Not found", { status: 404 })
		);
	},
};
import { routeAgentRequest } from "agents/routing";

export default {
	async fetch(request: Request, env: Env): Promise<Response> {
		return (
			(await routeAgentRequest(request, env, {
				cors: {
					"Access-Control-Allow-Origin": "https://app.example.com",
					"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
					"Access-Control-Allow-Headers": "Content-Type, Authorization",
					"Access-Control-Allow-Credentials": "true",
				},
			})) ?? new Response("Not found", { status: 404 })
		);
	},
} satisfies ExportedHandler<Env>;

匹配的 OPTIONS 请求会获得 CORS 标头,但不会到达对象。onBeforeRequest 返回的响应也会获得这些标头。WebSocket 升级响应不会添加这些标头。

放置位置

jurisdiction 和 locationHint 会应用于此调用路由到的每个对象:

import { routeAgentRequest } from "agents/routing";

export default {
	async fetch(request, env) {
		return (
			(await routeAgentRequest(request, env, {
				jurisdiction: "eu",
				locationHint: "weur",
			})) ?? new Response("Not found", { status: 404 })
		);
	},
};
import { routeAgentRequest } from "agents/routing";

export default {
	async fetch(request: Request, env: Env): Promise<Response> {
		return (
			(await routeAgentRequest(request, env, {
				jurisdiction: "eu",
				locationHint: "weur",
			})) ?? new Response("Not found", { status: 404 })
		);
	},
} satisfies ExportedHandler<Env>;

辖区内的对象与辖区外同名对象具有不同 ID。每次路由到某个对象时,都请使用相同的 jurisdiction。位置提示仅在首次创建对象时生效。可用值请参阅数据位置。

Props

props 会将 Worker 中的值传递给对象启动流程。每项能力的 onStart() 钩子和宿主的 onStart(props) 都会收到这些值。请使用 Lifecycle.install() 的第二个类型参数指定它们的类型:

import { DurableObject } from "cloudflare:workers";
import { Lifecycle } from "agents/lifecycle";
import { routeAgentRequest } from "agents/routing";

export class MyAgent extends DurableObject {
	lifecycle = Lifecycle.install(this);
	#plan = "free";

	onStart(props) {
		this.#plan = props?.plan ?? "free";
	}

	onRequest() {
		return Response.json({ plan: this.#plan });
	}
}

export default {
	async fetch(request, env) {
		const userId = request.headers.get("x-user-id") ?? "anonymous";
		return (
			(await routeAgentRequest(request, env, {
				props: { userId, plan: "pro" },
			})) ?? new Response("Not found", { status: 404 })
		);
	},
};
import { DurableObject } from "cloudflare:workers";
import { Lifecycle } from "agents/lifecycle";
import { routeAgentRequest } from "agents/routing";

type Props = { userId: string; plan: "free" | "pro" };

export class MyAgent extends DurableObject<Env> {
	readonly lifecycle = Lifecycle.install<Env, Props>(this);
	#plan: Props["plan"] = "free";

	onStart(props?: Props): void {
		this.#plan = props?.plan ?? "free";
	}

	onRequest(): Response {
		return Response.json({ plan: this.#plan });
	}
}

export default {
	async fetch(request: Request, env: Env): Promise<Response> {
		const userId = request.headers.get("x-user-id") ?? "anonymous";
		return (
			(await routeAgentRequest(request, env, {
				props: { userId, plan: "pro" },
			})) ?? new Response("Not found", { status: 404 })
		);
	},
} satisfies ExportedHandler<Env>;

Props 只会传递给冷对象。热对象已完成启动,会忽略这些值。不要将每个请求都需要的数据放在 props 中。请存储这些数据,或在每个请求中发送。

URL 匹配到哪个对象,这些 props 就会传给哪个对象。如需通过 RPC 和 props 启动对象,请调用 lifecycle.start(props)。更多信息,请参阅通过 RPC 调用对象。

重试

routingRetry 会重试平台标记为可重试且并非由过载引起的 Durable Object 错误。重试间隔会采用带随机抖动的指数退避。选项类型为 RoutingRetryOptions:

字段 默认值 说明
maxAttempts 3 尝试次数,包括第一次
baseDelayMs 100 退避的基础延迟,单位为毫秒
maxDelayMs 800 两次尝试之间的最大延迟,单位为毫秒
onRetry 无 每次重试前调用,并传入错误、尝试次数和延迟
import { routeAgentRequest } from "agents/routing";

export default {
	async fetch(request, env) {
		return (
			(await routeAgentRequest(request, env, {
				routingRetry: {
					maxAttempts: 5,
					onRetry: ({ attempt, delayMs, name }) => {
						console.warn(
							`Retrying ${name}, attempt ${attempt} in ${delayMs} ms`,
						);
					},
				},
			})) ?? new Response("Not found", { status: 404 })
		);
	},
};
import { routeAgentRequest } from "agents/routing";

export default {
	async fetch(request: Request, env: Env): Promise<Response> {
		return (
			(await routeAgentRequest(request, env, {
				routingRetry: {
					maxAttempts: 5,
					onRetry: ({ attempt, delayMs, name }) => {
						console.warn(
							`Retrying ${name}, attempt ${attempt} in ${delayMs} ms`,
						);
					},
				},
			})) ?? new Response("Not found", { status: 404 })
		);
	},
} satisfies ExportedHandler<Env>;

传入 routingRetry: false 可关闭重试。

这篇文档对您有帮助吗?