Skip to content

Commit ef610f8

Browse files
authored
Merge pull request #43 from irvinebroque/bib/remove-d1
Remove D1 and greatly simplify the example
2 parents 7e244c3 + 269d1b5 commit ef610f8

File tree

15 files changed

+2480
-2612
lines changed

15 files changed

+2480
-2612
lines changed

.env.test

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Local development environment variables
2+
#
3+
# INSTRUCTIONS:
4+
# 1. Copy this file to .env: cp .env.test .env
5+
# 2. Replace the placeholder values below with your actual values
6+
# 3. DO NOT commit the .env file to git (it contains secrets)
7+
# 4. Run this command to set the production secret:
8+
# echo <YOUR_ACTUAL_TOKEN> | wrangler secret put CLOUDFLARE_API_TOKEN
9+
10+
# Replace with your actual Cloudflare account ID
11+
CLOUDFLARE_ACCOUNT_ID=your_account_id_here
12+
13+
# Replace with your actual API token (Workers Scripts: Edit permission required)
14+
# To create: Workers dashboard -> API Tokens -> Create Token -> Custom -> Account: Workers Scripts: Edit
15+
CLOUDFLARE_API_TOKEN=your_api_token_here

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
node_modules
22
dist/**/*
33
.dev.vars
4+
.env
5+
.wrangler
6+
CLAUDE.md

README.md

Lines changed: 53 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -4,123 +4,103 @@
44
- [Docs](https://developers.cloudflare.com/cloudflare-for-platforms/workers-for-platforms)
55
- [Discord](https://discord.cloudflare.com/)
66

7-
For SaaS companies, it's challenging to keep up with the never ending requests for customizations. You want your development team to focus on building the core business instead of building and maintaining custom features for every customer use case. Workers for Platforms gives your customers the ability to build services and customizations (powered by Workers) while you retain full control over how their code is executed and billed. The **dynamic dispatch namespaces** feature makes this possible.
7+
This is a **minimal Workers for Platforms** example that demonstrates the core concepts of dynamic dispatch. The platform allows users to create and upload custom Workers through a simple web interface, then access them via friendly URLs.
88

9-
By creating a dispatch namespace and using the `dispatch_namespaces` binding in a regular fetch handler, you have a “dispatch Worker”:
9+
Workers for Platforms gives your customers the ability to build services and customizations (powered by Workers) while you retain full control over how their code is executed and billed. The **dynamic dispatch namespaces** feature makes this possible.
10+
11+
By creating a dispatch namespace and using the `dispatch_namespaces` binding in a regular fetch handler, you have a "dispatch Worker":
1012

1113
```javascript
1214
export default {
1315
async fetch(request, env) {
14-
// "dispatcher" is a binding defined in wrangler.toml
15-
// "customer-worker-1" is a script previously uploaded to the dispatch namespace
16-
const worker = env.dispatcher.get("customer-worker-1");
16+
// "dispatcher" is a binding defined in wrangler.jsonc
17+
// "my-user-worker" is a script previously uploaded to the dispatch namespace
18+
const worker = env.dispatcher.get("my-user-worker");
1719
return await worker.fetch(request);
1820
}
1921
}
2022
```
2123

22-
This is the perfect way for a platform to create boilerplate functions, handle routing to user Workers, and sanitize responses. You can manage thousands of Workers with a single Cloudflare Workers account!
24+
This is the perfect way for a platform to create boilerplate functions, handle routing to "user Workers", and sanitize responses. You can manage thousands of Workers with a single Cloudflare Workers account!
2325

2426
## In this example
2527

26-
A customer of the platform can upload Workers scripts with a form, and the platform will upload it to a dispatch namespace. An eyeball can request a script by url, and the platform will dynamically fetch and run the script and return the response to the eyeball. For simplicity, this project is a single Worker that does everything: serve HTML, dispatch Workers, etc. In a real application, it would be ideal to split this Worker into several.
27-
28-
Scripts uploaded to the dispatch namespace are tagged using Script Tags. The dispatch namespace API supports filtering scripts by Script Tag which enables useful CRUD workflows. This platform adds `customer_id` as a script tag, making it possible to do script access control and query customers' scripts.
29-
30-
Customers of the platform are stored in [Workers D1](https://blog.cloudflare.com/introducing-d1/) (sqlite database) with tokens to authenticate specific API interactions. This is not a specific Workers for Platforms feature, but it shows how easy it is to build out functionality for platform management. Beyond authentication, notice how extra data does not need to be stored or managed for the Workers for Platforms workflow!
31-
32-
Customer scripts can also be configured with [custom limits](https://developers.cloudflare.com/cloudflare-for-platforms/workers-for-platforms/platform/custom-limits/#custom-limits) and an [Outbound Worker](https://developers.cloudflare.com/cloudflare-for-platforms/workers-for-platforms/reference/outbound-workers/#outbound-workers) to control execution. These details are also stored in D1.
33-
34-
Lastly, the default template for a customer worker looks like this:
35-
```javascript
36-
import { platformThing } from "./platform_module.mjs";
37-
export default {
38-
async fetch(request, env, ctx) {
39-
return new Response("Hello! " + platformThing);
40-
}
41-
};
42-
```
28+
Users can upload Workers scripts through a simple web form. The platform uploads the script to a dispatch namespace and stores a name → Worker ID mapping in Workers KV. Users can then access their Workers via URLs like `/user-workers/my-worker`.
4329

44-
Notice how this script imports a module it doesn't define. The platform defines it! If you check `src/resource.ts`, you can see that we inject a module to the bundle when a customer uploads their script:
45-
```javascript
46-
const platformModuleContent = 'const platformThing = "This module is provided by the platform"; export { platformThing };';
47-
formData.append('platform_module', new File([platformModuleContent], 'platform_module.mjs', { type: 'application/javascript+module' }));
48-
```
49-
Since the platform has total control over how scripts are uploaded, it can provide or limit any functionality it needs.
30+
This minimal example focuses on the core Workers for Platforms concepts:
31+
- Dynamic dispatch using the `dispatcher` binding
32+
- Worker upload via the Cloudflare API
33+
- Simple name-based routing using KV storage
5034

51-
This project depends on:
35+
## Key Features
5236

53-
- [G4brym/workers-qb](https://github.com/G4brym/workers-qb) for interacting with D1.
54-
- [honojs/hono](https://github.com/honojs/hono) for request routing.
37+
- **Simple Worker Creation**: Web form for uploading Worker code
38+
- **Dynamic Dispatch**: Route requests to user Workers by name
39+
- **KV Storage**: Store friendly name mappings
40+
- **No Dependencies**: Pure Workers runtime with minimal external dependencies
5541

5642
## Getting started
5743

58-
Your Cloudflare account needs access to Workers for Platforms and D1.
44+
Your Cloudflare account needs access to Workers for Platforms.
5945

6046
1. Install the package and dependencies:
6147

6248
```
6349
npm install
6450
```
6551

66-
2. Create a D1 database and copy the ID into `wrangler.toml`. Make sure you update the `database_id` in wrangler.toml for your D1 binding afterwards:
52+
2. Create an API token with Workers Scripts (Edit) permission:
6753

68-
```
69-
npx wrangler d1 create workers-for-platforms-example-project
70-
```
54+
Visit [https://dash.cloudflare.com/?to=/:account/api-tokens](https://dash.cloudflare.com/?to=/:account/api-tokens) and create a new token with the "Workers Scripts (Edit)" permission.
7155

72-
3. Edit the `[vars]` in `wrangler.toml` and set the `DISPATCH_NAMESPACE_API_TOKEN` secret (instructions in `wrangler.toml`).
73-
For local development, you also have to create a `.dev.vars` file with the same environment variables:
56+
3. Copy the `.env.test` file to `.env` and set the `CLOUDFLARE_API_TOKEN` and `CLOUDFLARE_ACCOUNT_ID` secrets:
7457

7558
```sh
76-
DISPATCH_NAMESPACE_ACCOUNT_ID = "replace_me"
77-
DISPATCH_NAMESPACE_API_TOKEN = "replace_me"
59+
cp .env.test .env
7860
```
7961

80-
> To create an API Token, go to Workers dashboard -> click "API Tokens" on right sidebar. Then either:
81-
> 1. Click "API Tokens" on the right sidebar.
82-
> 2. Click "Create Token". Make sure you give this token at least "Account : Workers Scripts : Edit". This token is used with `Bearer`.
62+
Then edit the `.env` file with your actual values:
8363

84-
4. Create a namespace. Replace `$(ACCOUNT)`, `$(API_TOKEN)`, and `$(NAMESPACE)`:
85-
```
86-
npx wrangler dispatch-namespace create workers-for-platforms-example-project
64+
```sh
65+
CLOUDFLARE_ACCOUNT_ID = "your_actual_account_id"
66+
CLOUDFLARE_API_TOKEN = "your_actual_api_token"
8767
```
8868

89-
5. Run the Worker in dev mode:
69+
The `.env` file is already in `.gitignore` and will not be committed to git.
70+
71+
Then run the following commands to add these secrets to your Worker in production:
72+
9073
```
91-
npx wrangler dev --remote # local dev not currently supported
74+
npx wrangler secret put CLOUDFLARE_API_TOKEN
9275
```
93-
Or deploy to production:
76+
9477
```
95-
npx wrangler deploy
78+
npx wrangler secret put CLOUDFLARE_ACCOUNT_ID
9679
```
97-
> Dev mode will still use the configured dispatch namespace. Take care you're not accidentally modifying production!
98-
99-
Once the Worker is live, visit [localhost:8787](http://localhost:8787/) in a browser and click the `Initialize` link. Have fun!
10080

101-
For dev testing, here's a snippet to use in a NodeJS environment (like Chrome Dev Tools) to exercise the API:
81+
4. Create a KV namespace for Worker mappings:
10282

103-
```javascript
104-
await (await fetch("http://localhost:8787/script/my-customer-script", {
105-
"headers": {
106-
"X-Customer-Token": "d4e5f6"
107-
},
108-
"method": "PUT",
109-
"body": "...my-script-content..."
110-
})).text();
111-
```
83+
```
84+
npx wrangler kv:namespace create "WORKER_MAPPINGS"
85+
```
11286

113-
Or using curl:
87+
Copy the namespace ID and preview ID into `wrangler.jsonc` under the `kv_namespaces` binding.
11488

115-
```
116-
curl -X PUT http://localhost:8787/script/my-customer-script -H 'X-Customer-Token: d4e5f6' -d '...my-script-content...'
117-
```
89+
5. Create a dispatch namespace:
11890

119-
## Troubleshooting
91+
```
92+
npx wrangler dispatch-namespace create workers-for-platforms-example-project
93+
```
12094

121-
- Use `npx wrangler tail` to capture logs.
122-
- Try a re-publish and wait a minute.
95+
6. Run the Worker in dev mode:
96+
```
97+
npm run dev
98+
```
99+
Or deploy to production:
100+
```
101+
npm run deploy
102+
```
123103

124-
## Example project roadmap
104+
Once the Worker is live, visit [localhost:8787](http://localhost:8787/) in a browser. You can create a new Worker via the "/upload" link. Access your Workers at `/user-workers/{name}`!
125105

126-
- Showcase a Trace Worker and Workers Logpush to collect trace events for both the platform Worker and dispatched customer Workers.
106+
Then access it at: `http://localhost:8787/user-workers/my-worker`

0 commit comments

Comments
 (0)