← Cloudflare Durable Objects / durable-objects / best-practices
Вызов методов
Вызов методов Durable Object
Все новые проекты и существующие проекты с датой совместимости не ранее 2024-04-03 предпочтительнее вызывать Удалённый вызов процедур (RPC) методы, определённые в Durable Object class.
Проекты, которым нужен цикл HTTP-запрос/ответ, а также устаревшие проекты могут по-прежнему вызывать fetch()-обработчик класса Durable Object.
Вызов RPC-методов
Написав класс Durable Object, наследующий встроенный тип DurableObject, публичные методы класса Durable Object доступны как Методы RPC, который можно вызвать с помощью DurableObjectStub из Worker.
Все вызовы 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) {
// 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 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) {
// 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 rpcResponse = await stub.sayHello();
return new Response(rpcResponse);
},
} satisfies ExportedHandler<Env>;См. Создание счётчика для полного примера.
Вызов fetch обработчик
Если ваш проект использует дату совместимости раньше 2024-04-03, или должен отправить Request объект и возвращает Response объект, отправляйте запросы к Durable Object через обработчик fetch.
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>; URL связанный с Request объект, переданный в fetch()-обработчик вашего Durable Object должен быть корректно сформированным 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>;