Tutorial
This guide will instruct you through:
- Writing a Durable Object class.
- Writing a Worker which invokes methods on a Durable Object.
- Deploying a Durable Object.
If you wish to learn more about Durable Objects, refer to What are Durable Objects?.
- Sign up for a Cloudflare account ↗.
- Install
Node.js
↗.
Node.js version manager
Use a Node version manager like Volta ↗ or nvm ↗ to avoid permission issues and change Node.js versions. Wrangler, discussed later in this guide, requires a Node version of 16.17.0
or later.
To enable Durable Objects, you will need to purchase the Workers Paid plan:
- Log in to the Cloudflare dashboard ↗, and select your account.
- Go to Workers & Pages > Plans.
- Select Purchase Workers Paid and complete the payment process to enable Durable Objects.
Durable Objects are accessed from a Worker.
To create a Worker project, run:
npm create cloudflare@latest -- durable-object-starter
pnpm create cloudflare@latest durable-object-starter
yarn create cloudflare durable-object-starter
Running create cloudflare@latest
will install Wrangler, the Workers CLI. You will use Wrangler to test and deploy your project.
For setup, select the following options:
- For What would you like to start with?, choose
Hello World example
. - For Which template would you like to use?, choose
Hello World Worker using Durable Objects
. - For Which language do you want to use?, choose
JavaScript / TypeScript
. - For Do you want to use git for version control?, choose
Yes
. - For Do you want to deploy your application?, choose
No
(we will be making some changes before deploying).
This will create a new directory, which will include either a src/index.js
or src/index.ts
file to write your code and a wrangler.jsonc
configuration file.
Move into your new directory:
cd durable-object-starter
Durable Objects are defined by a exporting a standard JavaScript class which extends from the DurableObject
base class.
Your MyDurableObject
class will have a constructor with two parameters. The first parameter, state
, passed to the class constructor contains state specific to the Durable Object, including methods for accessing storage. The second parameter, env
, contains any bindings you have associated with the Worker when you uploaded it.
import { DurableObject } from "cloudflare:workers";
export class MyDurableObject extends DurableObject { constructor(state, env) {}}
import { DurableObject } from "cloudflare:workers";
export class MyDurableObject extends DurableObject { constructor(state: DurableObjectState, env: Env) {}}
Workers can invoke public methods defined on a Durable Object via Remote Procedure Call (RPC).
The sayHello
method demonstrates this capability:
import { DurableObject } from "cloudflare:workers";
export class MyDurableObject extends DurableObject { constructor(state, env) {}
async sayHello() { return "Hello, World!"; }}
import { DurableObject } from "cloudflare:workers";
export class MyDurableObject extends DurableObject { constructor(state: DurableObjectState, env: Env) {}
async sayHello(): Promise<string> { return "Hello, World!"; }}
As mentioned previously, methods on a Durable Object class are invoked by a Worker. This is done by creating an ID refering to an instance of the Durable Object class, getting a stub that refers to a particular instance of a Durable Object class, and invoking methods on that stub.
The fetch handler should look like the following:
// Workerexport default { async fetch(request, env) { // Every unique ID refers to an individual instance of the Durable Object class const id = env.MY_DURABLE_OBJECT.idFromName("foo");
// A stub is a client used to invoke methods on the Durable Object const stub = env.MY_DURABLE_OBJECT.get(id);
// Methods on the Durable Object are invoked via the stub const rpcResponse = await stub.sayHello();
return new Response(rpcResponse); },};
// Workerexport default { async fetch(request, env, ctx): Promise<Response> { // Every unique ID refers to an individual instance of the Durable Object class const id = env.MY_DURABLE_OBJECT.idFromName("foo");
// A stub is a client used to invoke methods on the Durable Object const stub = env.MY_DURABLE_OBJECT.get(id);
// Methods on the Durable Object are invoked via the stub const rpcResponse = await stub.sayHello();
return new Response(rpcResponse); },} satisfies ExportedHandler<Env>;
To allow a Worker to invoke methods on a Durable Object, the Worker must have a Durable Object binding in the project's Wrangler configuration file. The binding is configured to use a particular Durable Object class.
{ "durable_objects": { "bindings": [ { "name": "MY_DURABLE_OBJECT", "class_name": "MyDurableObject" } ] }}
[[durable_objects.bindings]]name = "MY_DURABLE_OBJECT"class_name = "MyDurableObject"
The [[durable_objects.bindings]]
section contains the following fields:
name
- Required. The binding name to use within your Worker.class_name
- Required. The class name you wish to bind to.script_name
- Optional. The name of the Worker if the Durable Object is external to this Worker.environment
- Optional. The environment of thescript_name
to bind to.
Refer to Wrangler Configuration for more detail.
A migration is a mapping process from a class name to a runtime state. You perform a migration when creating a new Durable Object class, or when renaming, deleting or transferring an existing Durable Object class.
Migrations are performed through the [[migrations]]
configurations key in your Wrangler file.
The Durable Object migration to create a new Durable Object class will look like the following in your Worker's Wrangler file:
{ "migrations": [ { "tag": "v1", "new_classes": [ "MyDurableObject" ] } ]}
[[migrations]]tag = "v1" # Should be unique for each entrynew_classes = ["MyDurableObject"] # Array of new classes
A Durable Object class can only have a single storage type, which cannot be changed after the Durable Object class is created.
To configure SQL storage and API, replace new_classes
with new_sqlite_classes
in your Worker's Wrangler file:
{ "migrations": [ { "tag": "v1", "new_sqlite_classes": [ "MyDurableObject" ] } ]}
[[migrations]]tag = "v1" # Should be unique for each entrynew_sqlite_classes = ["MyDurableObject"] # Array of new classes
Refer to Durable Objects migrations to learn more about the migration process.
To test your Durable Object locally, run wrangler dev
:
npx wrangler dev
In your console, you should see aHello world
string returned by the Durable Object.
To deploy your Durable Object Worker:
npx wrangler deploy
Once deployed, you should be able to see your newly created Durable Object Worker on the Cloudflare dashboard ↗, Workers & Pages > Overview.
Preview your Durable Object Worker at <YOUR_WORKER>.<YOUR_SUBDOMAIN>.workers.dev
.
By finishing this tutorial, you have successfully created, tested and deployed a Durable Object.
- Send requests to Durable Objects
- Miniflare ↗ - Helpful tools for mocking and testing your Durable Objects.