Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -7,217 +7,31 @@ sidebar:

import { Render, PackageManagers, WranglerConfig } from "~/components";

To test your [Dispatch Worker](/cloudflare-for-platforms/workers-for-platforms/reference/how-workers-for-platforms-works/#dynamic-dispatch-worker), [user Worker](/cloudflare-for-platforms/workers-for-platforms/reference/how-workers-for-platforms-works/#user-workers) and [Outbound Worker](/cloudflare-for-platforms/workers-for-platforms/configuration/outbound-workers/) before deploying to production, you can use [Wrangler](/workers/wrangler) for development and testing.
Test changes to your [dynamic dispatch Worker](/cloudflare-for-platforms/workers-for-platforms/reference/how-workers-for-platforms-works/#dynamic-dispatch-worker) by running the dynamic dispatch Worker locally but connecting it to User Workers deployed in production.

:::note
This is helpful when:
- **Testing routing changes** and validating that updates continue to work with deployed User Workers
- **Adding new middleware** like authentication, rate limiting, or logging to the dynamic dispatch Worker
- **Debugging issues** in the dynamic dispatcher that may be impacting deployed User Workers

Support for Workers for Platforms with `wrangler dev` in local mode is experimental and may change in the future. Use the prerelease branch: `wrangler@dispatch-namespaces-dev` to try Workers for Platforms locally.
:::
### How to use remote dispatch namespaces

## 1. Create a user worker

<PackageManagers
type="create"
pkg="cloudflare@latest"
args={"customer-worker-1"}
/>

<Render
file="c3-post-run-steps"
product="workers"
params={{
category: "hello-world",
type: "Worker only",
lang: "JavaScript",
}}
/>

Then, move into the newly created directory:

```sh
cd customer-worker-1
```

Update the `src/index.js` file for customer-worker-1:

```javascript
export default {
async fetch(request) {
// make a subrequest to the internet
const response = await fetch("https://example.com");
return new Response(
`user worker got "${await response.text()}" from fetch`,
);
},
};
```

Update the Wrangler file for customer-worker-1 and add the dispatch namespace:

<WranglerConfig>

```toml
# ... other content above ...

dispatch_namespace = "my-namespace"
```

</WranglerConfig>

## 2. Create a dispatch worker

<PackageManagers
type="create"
pkg="cloudflare@latest"
args={"dispatch-worker"}
/>

<Render
file="c3-post-run-steps"
product="workers"
params={{
category: "hello-world",
type: "Worker only",
lang: "JavaScript",
}}
/>

Then, move into the newly created directory:

```sh
cd dispatch-worker
```

Update the `src/index.js` file for dispatch-worker:

```javascript
export default {
async fetch(request, env) {
// get the user Worker, specifying parameters that the Outbound Worker will see when it intercepts a user worker's subrequest
const customerScript = env.DISPATCH_NAMESPACE.get(
"customer-worker-1",
{},
{
outbound: {
paramCustomerName: "customer-1",
},
},
);
// invoke user Worker
return await customerScript.fetch(request);
},
};
```

Update the Wrangler file for dispatch-worker and add the dispatch namespace binding:

<WranglerConfig>

```toml
# ... other content above ...

[[dispatch_namespaces]]
binding = "DISPATCH_NAMESPACE"
namespace = "my-namespace"
outbound = { service = "outbound-worker", parameters = ["paramCustomerName"] }
```

</WranglerConfig>

## 3. Create an Outbound Worker

<PackageManagers
type="create"
pkg="cloudflare@latest"
args={"outbound-worker"}
/>

<Render
file="c3-post-run-steps"
product="workers"
params={{
category: "hello-world",
type: "Worker only",
lang: "JavaScript",
}}
/>

Then, move into the newly created directory:

```sh
cd outbound-worker
```

Update the `src/index.js` file for outbound-worker:

```javascript
export default {
async fetch(request, env) {
const { paramCustomerName } = env;
// use the parameters passed by the dispatcher to know what this user this request is for
// and return custom content back to the user worker
return new Response(
`intercepted a request for ${paramCustomerName} by the outbound`,
);
},
};
```

## 4. Start local dev session for your Workers

In separate terminals, start a local dev session for each of your Workers.

For your dispatcher Worker:

```sh
cd dispatch-worker
npx wrangler@dispatch-namespaces-dev dev --port 8600
```

For your outbound Worker:

```sh
cd outbound-worker
npx wrangler@dispatch-namespaces-dev dev --port 8601
```

And for your user Worker:

```sh
cd customer-worker-1
npx wrangler@dispatch-namespaces-dev dev --port 8602
```

## 5. Test your requests

Send a request to your dispatcher Worker:

```sh
curl http://localhost:8600
```

```sh output
# -> user worker got "intercepted a request for customer-1 by the outbound" from fetch
```

## Remote dispatch namespaces

You can configure dispatch namespace bindings to connect to remote dispatch namespaces during local development by setting [`experimental_remote = true`](/workers/development-testing/#remote-bindings):
In the dynamic dispatch Worker's Wrangler file, configure the [dispatch namespace binding](/workers/wrangler/configuration/#dispatch-namespace-bindings-workers-for-platforms) to connect to the remote namespace by setting [`experimental_remote = true`](/workers/development-testing/#remote-bindings):

<WranglerConfig>
```jsonc title="wrangler.jsonc"
{
"dispatch_namespaces": [
{
"binding": "DISPATCH_NAMESPACE",
"namespace": "testing",
"namespace": "production",
"experimental_remote": true
}
]
}
```
</WranglerConfig>

This allows you to run your [dynamic dispatch Worker](/cloudflare-for-platforms/workers-for-platforms/reference/how-workers-for-platforms-works/#dynamic-dispatch-worker) locally, while connecting it to your remote dispatch namespace binding. You can then test changes to your core dispatching logic against real, deployed [user Workers](/cloudflare-for-platforms/workers-for-platforms/reference/how-workers-for-platforms-works/#user-workers).
This tells your dispatch Worker that's running locally to connect to the remote `production` namespace. When you run `wrangler dev`, your Dispatch Worker will route requests to the User Workers deployed in that namespace.

For more information about remote bindings during local development, refer to [remote bindings documentation](/workers/development-testing/#remote-bindings).