所有新项目以及兼容性日期大于或等于 2024-04-03 的现有项目,应优先调用 Durable Object 类 上定义的远程过程调用 (RPC) 方法。
需要 HTTP 请求/响应流程或旧版项目可以继续调用 Durable Object 类上的 fetch() 处理器。
通过编写继承内置类型 DurableObject 的 Durable Object 类,Durable Objects 类上的公共方法会暴露为 RPC 方法,您可以使用 Worker 中的 DurableObjectStub 调用。
所有 RPC 调用都是异步的,接受和返回可序列化类型,并将异常传播给调用者(无堆栈跟踪)。请参阅 Workers RPC 了解完整详情。
import { DurableObject } from "cloudflare:workers";
// Durable Object
export class MyDurableObject extends DurableObject {
constructor(ctx, env) {
super(ctx, env);
}
async sayHello() {
return "Hello, World!";
}
}
// Worker
export default {
async fetch(request, env) {
// stub 是用于调用 Durable Object 上方法的客户端
const stub = env.MY_DURABLE_OBJECT.getByName("foo");
// Durable Object 上的方法是通过 stub 调用的
const rpcResponse = await stub.sayHello();
return new Response(rpcResponse);
},
};import { DurableObject } from "cloudflare:workers";
export interface Env {
MY_DURABLE_OBJECT: DurableObjectNamespace<MyDurableObject>;
}
// Durable Object
export class MyDurableObject extends DurableObject {
constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env);
}
async sayHello(): Promise<string> {
return "Hello, World!";
}
}
// Worker
export default {
async fetch(request, env) {
// stub 是用于调用 Durable Object 上方法的客户端
const stub = env.MY_DURABLE_OBJECT.getByName("foo");
// Durable Object 上的方法是通过 stub 调用的
const rpcResponse = await stub.sayHello();
return new Response(rpcResponse);
},
} satisfies ExportedHandler<Env>;请参阅构建计数器了解完整示例。
如果您的项目卡在 2024-04-03 之前的兼容性日期,或需要发送 Request 对象并返回 Response 对象,则应通过 fetch 处理器向 Durable Object 发送请求。
import { DurableObject } from "cloudflare:workers";
// Durable Object
export class MyDurableObject extends DurableObject {
constructor(ctx, env) {
super(ctx, env);
}
async fetch(request) {
return new Response("Hello, World!");
}
}
// Worker
export default {
async fetch(request, env) {
// A stub is a client used to invoke methods on the Durable Object
const stub = env.MY_DURABLE_OBJECT.getByName("foo");
// Methods on the Durable Object are invoked via the stub
const response = await stub.fetch(request);
return response;
},
};import { DurableObject } from "cloudflare:workers";
export interface Env {
MY_DURABLE_OBJECT: DurableObjectNamespace<MyDurableObject>;
}
// Durable Object
export class MyDurableObject extends DurableObject {
constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env);
}
async fetch(request: Request): Promise<Response> {
return new Response("Hello, World!");
}
}
// Worker
export default {
async fetch(request, env) {
// A stub is a client used to invoke methods on the Durable Object
const stub = env.MY_DURABLE_OBJECT.getByName("foo");
// Methods on the Durable Object are invoked via the stub
const response = await stub.fetch(request);
return response;
},
} satisfies ExportedHandler<Env>;传递给 Durable Object fetch() 处理器的 Request 对象关联的 URL 必须是格式良好的 URL,但不必是公开可解析的主机名。
没有 RPC 时,客户经常构造对应 Durable Object 私有方法的请求,并从 fetch 处理器分发请求。在此示例中 RPC 显然更符合人体工程学。
import { DurableObject } from "cloudflare:workers";
// Durable Object
export class MyDurableObject extends DurableObject {
constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env);
}
private hello(name) {
return new Response(`Hello, ${name}!`);
}
private goodbye(name) {
return new Response(`Goodbye, ${name}!`);
}
async fetch(request) {
const url = new URL(request.url);
let name = url.searchParams.get("name");
if (!name) {
name = "World";
}
switch (url.pathname) {
case "/hello":
return this.hello(name);
case "/goodbye":
return this.goodbye(name);
default:
return new Response("Bad Request", { status: 400 });
}
}
}
// Worker
export default {
async fetch(_request, env, _ctx) {
// A stub is a client used to invoke methods on the Durable Object
const stub = env.MY_DURABLE_OBJECT.getByName("foo");
// Invoke the fetch handler on the Durable Object stub
let response = await stub.fetch("http://do/hello?name=World");
return response;
},
};import { DurableObject } from "cloudflare:workers";
export interface Env {
MY_DURABLE_OBJECT: DurableObjectNamespace<MyDurableObject>;
}
// Durable Object
export class MyDurableObject extends DurableObject {
constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env);
}
private hello(name: string) {
return new Response(`Hello, ${name}!`);
}
private goodbye(name: string) {
return new Response(`Goodbye, ${name}!`);
}
async fetch(request: Request): Promise<Response> {
const url = new URL(request.url);
let name = url.searchParams.get("name");
if (!name) {
name = "World";
}
switch (url.pathname) {
case "/hello":
return this.hello(name);
case "/goodbye":
return this.goodbye(name);
default:
return new Response("Bad Request", { status: 400 });
}
}
}
// Worker
export default {
async fetch(_request, env, _ctx) {
// A stub is a client used to invoke methods on the Durable Object
const stub = env.MY_DURABLE_OBJECT.getByName("foo");
// Invoke the fetch handler on the Durable Object stub
let response = await stub.fetch("http://do/hello?name=World");
return response;
},
} satisfies ExportedHandler<Env>;