Skip to main content

Invoke methods

还没翻译译自英文(developers.cloudflare.com)本页 21 段都还没译

Invoking methods on a Durable Object

All new projects and existing projects with a compatibility date greater than or equal to 2024-04-03 should prefer to invoke Remote Procedure Call (RPC) methods defined on a Durable Object class.

Projects requiring HTTP request/response flows or legacy projects can continue to invoke the fetch() handler on the Durable Object class.

Invoke RPC methods

By writing a Durable Object class which inherits from the built-in type DurableObject, public methods on the Durable Objects class are exposed as RPC methods, which you can call using a DurableObjectStub from a Worker.

All RPC calls are asynchronous, accept and return serializable types, and propagate exceptions to the caller without a stack trace. Refer to Workers RPC for complete details.

JavaScriptTypeScript

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);
	},
};

Note

With RPC, the DurableObject superclass defines ctx and env as class properties. What was previously called state is now called ctx when you extend the DurableObject class. The name ctx is adopted rather than state for the DurableObjectState interface to be consistent between DurableObject and WorkerEntrypoint objects.

Refer to Build a Counter for a complete example.

Invoking the fetch handler

If your project is stuck on a compatibility date before 2024-04-03, or has the need to send a Request object and return a Response object, then you should send requests to a Durable Object via the fetch handler.

JavaScriptTypeScript

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;
	},
};

The URL associated with the Request object passed to the fetch() handler of your Durable Object must be a well-formed URL, but does not have to be a publicly-resolvable hostname.

Without RPC, customers frequently construct requests which corresponded to private methods on the Durable Object and dispatch requests from the fetch handler. RPC is obviously more ergonomic in this example.

JavaScriptTypeScript

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;
	},
};