Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move reference documentation out of Durable Objects best practices and other fixes #17445

Merged
merged 6 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 5 additions & 14 deletions src/content/docs/durable-objects/api/id.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ sidebar:
order: 2
---

import { Tabs, TabItem } from "~/components";
import { Render, Tabs, TabItem } from "~/components";

## Description

The `DurableObjectId` interface refers to a new or existing Durable Object instance. This interface is most frequently used by [`DurableObjectNamespace::get`](/durable-objects/api/namespace/#get) to obtain a stub for submitting requests to a Durable Object instance.
A Durable Object ID is a 64-digit hexadecimal number used to identify a Durable Object instance. Not all 64-digit hex numbers are valid IDs. Durable Object IDs are constructed indirectly via the [`DurableObjectNamespace`](/durable-objects/api/namespace) interface.

Note that creating an ID for a Durable Object instance does not create the Durable Object. The Durable Object is created lazily after calling [`DurableObjectNamespace::get`](/durable-objects/api/namespace/#get) to create a [`DurableObjectStub`](/durable-objects/api/stub) from a `DurableObjectId`. This ensures that objects are not constructed until they are actually accessed.
The `DurableObjectId` interface refers to a new or existing Durable Object instance. This interface is most frequently used by [`DurableObjectNamespace::get`](/durable-objects/api/namespace/#get) to obtain a [`DurableObjectStub`](/durable-objects/api/stub) for submitting requests to a Durable Object instance. Note that creating an ID for a Durable Object instance does not create the Durable Object. The Durable Object is created lazily after creating a stub from a `DurableObjectId`. This ensures that objects are not constructed until they are actually accessed.

:::note[`DurableObjectId`]
:::note[Logging]

If you are experiencing an issue with a particular Durable Object instance, you may wish to log the `DurableObjectId` from your Worker and include it in your Cloudflare support request.

Expand All @@ -25,16 +25,7 @@ If you are experiencing an issue with a particular Durable Object instance, you

`toString` converts a `DurableObjectId` to a 64 digit hex string. This string is useful for logging purposes or storing the `DurableObjectId` elsewhere, for example, in a session cookie. This string can be used to reconstruct a `DurableObjectId` via `DurableObjectNamespace::idFromString`.

```js
// Create a new unique ID
const id = env.MY_DURABLE_OBJECT.newUniqueId();
// Convert the ID to a string to be saved elsewhere, e.g. a session cookie
const session_id = id.toString();

...
// Recreate the ID from the string
const id = env.MY_DURABLE_OBJECT.idFromString(session_id);
```
<Render file="example-id-from-string" />

#### Parameters

Expand Down
33 changes: 16 additions & 17 deletions src/content/docs/durable-objects/api/namespace.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ sidebar:
order: 1
---

import { Tabs, TabItem } from "~/components";
import { Render, Tabs, TabItem } from "~/components";

## Description

The `DurableObjectNamespace` interface is used to obtain a reference to a new or existing Durable Object instance. The interface is accessible from the fetch handler on a Cloudflare Worker via the `env` parameter, which is the standard interface when referencing bindings declared in `wrangler.toml`.
A Durable Object namespace is a set of Durable Object instances that are backed by the same Durable Object class. There is only one Durable Object namespace per class. A Durable Object namespace can contain any number of Durable Object instances.

The `DurableObjectNamespace` interface is used to obtain a reference to new or existing Durable Object instances. The interface is accessible from the fetch handler on a Cloudflare Worker via the `env` parameter, which is the standard interface when referencing bindings declared in `wrangler.toml`.

This interface defines several [methods](/durable-objects/api/namespace/#methods) that can be used to create an ID for a Durable Object instance. Note that creating an ID for a Durable Object instance does not create the Durable Object. The Durable Object is created lazily after calling [`DurableObjectNamespace::get`](/durable-objects/api/namespace/#get) to create a [`DurableObjectStub`](/durable-objects/api/stub) from a `DurableObjectId`. This ensures that objects are not constructed until they are actually accessed.

Expand Down Expand Up @@ -69,7 +71,7 @@ export default {

### `idFromName`

`idFromName` creates a [`DurableObjectId`](/durable-objects/api/id) which refers to an individual instance of the Durable Object class from a particular name.
`idFromName` creates a unique [`DurableObjectId`](/durable-objects/api/id) which refers to an individual instance of the Durable Object class. Named Durable Object instances are the most common method of referring to Durable Object instances.

```js
const fooId = env.MY_DURABLE_OBJECT.idFromName("foo");
Expand All @@ -86,16 +88,18 @@ const barId = env.MY_DURABLE_OBJECT.idFromName("bar");

### `newUniqueId`

`newUniqueId` creates a `DurableObjectId` which refers to an individual instance of the Durable Object class.
`newUniqueId` creates a randomly generated and unique [`DurableObjectId`](/durable-objects/api/id) which refers to an individual instance of the Durable Object class. IDs created using `newUniqueId`, will need to be stored as a string in order to refer to the same Durable Object again in the future. For example, the ID can be stored in Workers KV, another Durable Object instance, or in a cookie in the user's browser.

```js
const id = env.MY_DURABLE_OBJECT.newUniqueId();
const euId = env.MY_DURABLE_OBJECT.newUniqueId({ jurisdiction: "eu" });
```

:::note[`newUniqueId`]
:::note[`newUniqueId` results in lower request latency at first use]

The first time you get a Durable Object stub based on an ID derived from a name, the system has to take into account the possibility that a Worker on the opposite side of the world could have coincidentally accessed the same named Durable Object at the same time. To guarantee that only one instance of the Durable Object is created, the system must check that the Durable Object has not been created anywhere else. Due to the inherent limit of the speed of light, this round-the-world check can take up to a few hundred milliseconds. `newUniqueId` can skip this check.

IDs created by `newUniqueId` will result in lower latencies when getting a [`DurableObjectStub`](/durable-objects/api/stub) relative to [`idFromName`](/durable-objects/api/namespace/#idfromname).
After this first use, the location of the Durable Object instance will be cached around the world so that subsequent lookups are faster.

:::

Expand All @@ -109,16 +113,9 @@ IDs created by `newUniqueId` will result in lower latencies when getting a [`Dur

### `idFromString`

`idFromString` creates a [`DurableObjectId`](/durable-objects/api/id) from a previously generated ID that has been converted to a string. This method ensures the ID is valid, for example, it checks that the ID consists of 64 hex digits.
`idFromString` creates a [`DurableObjectId`](/durable-objects/api/id) from a previously generated ID that has been converted to a string. This method throws an exception if the ID is invalid, for example, if the ID was not created from the same `DurableObjectNamespace`.

```js
// Create a new unique ID
const id = env.MY_DURABLE_OBJECT.newUniqueId();
// Save the unique ID elsewhere, e.g. a session cookie via id.toString()
...
// Recreate the ID from the string
const id = env.MY_DURABLE_OBJECT.idFromString(session_id);
```
<Render file="example-id-from-string" />

#### Parameters

Expand All @@ -132,14 +129,17 @@ const id = env.MY_DURABLE_OBJECT.idFromString(session_id);

`get` obtains a [`DurableObjectStub`](/durable-objects/api/stub) from a [`DurableObjectId`](/durable-objects/api/id) which can be used to invoke methods on a Durable Object instance.

This method returns the stub immediately, often before a connection has been established to the Durable Object instance. This allows requests to be sent to the instance right away, without waiting for a network round trip.

```js
const id = env.MY_DURABLE_OBJECT.newUniqueId();
const stub = env.MY_DURABLE_OBJECT.get(id);
```

#### Parameters

- A required [`DurableObjectId`](/durable-objects/api/id) and an optional object with the key `locationHint` and value of a [locationHint](/durable-objects/reference/data-location/#provide-a-location-hint) string.
- A required [`DurableObjectId`](/durable-objects/api/id)
- An optional object with the key `locationHint` and value of a [locationHint](/durable-objects/reference/data-location/#provide-a-location-hint) string.

#### Return values

Expand All @@ -165,4 +165,3 @@ const euId = subnamespace.idFromName("foo");
## Related resources

- [Durable Objects: Easy, Fast, Correct – Choose Three](https://blog.cloudflare.com/durable-objects-easy-fast-correct-choose-three/).
- [Durable Objects best practices](/durable-objects/best-practices/access-durable-objects-from-a-worker/).
76 changes: 5 additions & 71 deletions src/content/docs/durable-objects/api/stub.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,83 +5,17 @@ sidebar:
order: 3
---

import { Tabs, TabItem } from "~/components";
import { Render } from "~/components";

## Description

The `DurableObjectStub` interface is used to obtain a reference a Durable Object instance and invoke methods on that instance. The type of `DurableObjectStub` is generic to allow for RPC methods to be invoked on the stub.
The `DurableObjectStub` interface is a client used to invoke methods on a remote Durable Object instance. The type of `DurableObjectStub` is generic to allow for RPC methods to be invoked on the stub.

<Tabs> <TabItem label="JavaScript" icon="seti:javascript">
Durable Objects implement E-order semantics, a concept deriving from the [E distributed programming language](<https://en.wikipedia.org/wiki/E_(programming_language)>). When you make multiple calls to the same Durable Object, it is guaranteed that the calls will be delivered to the remote Durable Object in the order in which you made them. E-order semantics makes many distributed programming problems easier. E-order is implemented by the [Cap'n Proto](https://capnproto.org) distributed object-capability RPC protocol, which Cloudflare Workers uses for internal communications.

```js
import { DurableObject } from "cloudflare:workers";

// Durable Object
export class MyDurableObject extends DurableObject {
constructor(ctx, env) {
super(ctx, env);
}

sayHello() {
return "Hello, World!";
}
}

// Worker
export 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 instance
const stub = env.MY_DURABLE_OBJECT.get(id);

// Methods on the Durable Object are invoked via the stub
const rpcResponse = stub.sayHello();

return new Response(rpcResponse);
},
};
```

</TabItem> <TabItem label="TypeScript" icon="seti:typescript">

```ts
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(): String {
return "Hello, World!";
}
}

// Worker
export 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 instance
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>;
```
If an exception is thrown by a Durable Object stub all in-flight calls and future calls will fail with [exceptions](/durable-objects/observability/troubleshooting/). To continue invoking methods on a remote Durable Object instance a Worker must recreate the stub. There are no ordering guarantees between different stubs.

</TabItem> </Tabs>
<Render file="example-rpc" />

## Properties

Expand Down

This file was deleted.

Loading
Loading