Cloudflare Workers
KV, Workers AI and the Vitest setup we use for edge workers
We leverage Cloudflare Workers for a variety of tasks that we want to run on the edge.
Quick reference
The following command line snippets assume you have Wrangler installed and connected to your Cloudflare account.
Cloudflare Workers KV
Cloudflare has a key-value store that can be used to store data that can be accessed by workers. This is an easy way to read and write data without the overhead of a database.
Creating a key-value namespace
To create a new key-value namespace, run the following command:
wrangler kv namespace create <YOUR_NAMESPACE>
After running this, you’ll want to bind your namespace to your worker. This is
done in the wrangler.toml file.
kv-namespaces = [
{ binding = "<YOUR_NAMESPACE>", id = "<YOUR_NAMESPACE_ID>" }
]
You’ll also most likely want to create a preview namespace for local development.
Simply add the --preview flag to the create command:
wrangler kv namespace create <YOUR_NAMESPACE> --preview
Then add the preview namespace to your wrangler.toml file:
kv-namespaces = [
{ binding = "<YOUR_NAMESPACE>", id = "<YOUR_NAMESPACE_ID>", preview_id = "<YOUR_NAMESPACE_ID_PREVIEW>" }
]
Reading and writing to KV
With Wrangler:
To use the preview environment, add --preview to the command.
# Read from KV
wrangler kv key get --binding=YOUR_NAMESPACE "some-key"
# Write to KV
wrangler kv key put --binding=YOUR_NAMESPACE "some-key" "some-value"
In your worker code:
Your worker will automatically use the preview environment when running locally,
but you can use the normal environment by adding the --remote flag when running
wrangler dev.
// Read from KV
const value = await env.MY_NAMESPACE.get('some-key');
// Write to KV
await env.MY_NAMESPACE.put('some-key', 'some-value');
Workers AI
Workers AI easily lets you use a variety of AI models in your code.
Adding Workers AI to your worker
Simply add the following to your wrangler.toml file:
[ai]
binding = "AI"
Then, in your worker code:
const response = await env.AI.run('<some-model>', {
prompt: 'Write a haiku about WordPress',
});
Testing workers
You can use the Workers Vitest integration to easily add automated tests to your worker.
Getting started
Add the dependencies to your project:
Note: check the
Cloudflare Workers Vitest integration docs
for the latest compatible version of vitest.
npm install vitest --save-dev
npm install @cloudflare/vitest-pool-workers --save-dev
Then create a vitest.config.js file in your project root:
import { cloudflareTest } from '@cloudflare/vitest-pool-workers';
import { defineConfig } from 'vitest/config';
export default defineConfig({
plugins: [
cloudflareTest({
singleWorker: true,
wrangler: { configPath: './wrangler.toml' },
}),
],
});
Finally, write your tests in a test directory in your project root:
import { env } from "cloudflare:workers";
import {
createExecutionContext,
waitOnExecutionContext,
} from "cloudflare:test";
import { describe, it, expect } from "vitest";
// Import your worker so you can unit test it
import worker from "../src";
// For now, you'll need to do something like this to get a correctly-typed
// `Request` to pass to `worker.fetch()`.
const IncomingRequest = Request;
describe("Hello World worker", () => {
it("responds with Hello World!", async () => {
const request = new IncomingRequest("http://example.com/404");
// Create an empty context to pass to `worker.fetch()`
const ctx = createExecutionContext();
const response = await worker.fetch(request, env, ctx);
// Wait for all `Promise`s passed to `ctx.waitUntil()` to settle before running test assertions
await waitOnExecutionContext(ctx);
expect(response.status).toBe(404);
expect(await response.text()).toBe("Not found");
});
});
Tests with Workers KV
import { SELF } from 'cloudflare:test';
import { it } from 'vitest';
it('stores in KV namespace', async ({ expect }) => {
let response = await SELF.fetch('https://example.com/kv/key', {
method: 'PUT',
body: 'value',
});
expect(response.status).toBe(204);
response = await SELF.fetch('https://example.com/kv/key');
expect(response.status).toBe(200);
expect(await response.text()).toBe('value');
});
Testing with multiple workers
Testing with multiple workers
is a bit more complex, as you can only read the wrangler.toml file for one
worker at a time. You’ll need to scaffold out the options for each worker in your
vitest.config.js file:
import { cloudflareTest } from '@cloudflare/vitest-pool-workers';
import { defineConfig } from 'vitest/config';
export default defineConfig({
plugins: [
cloudflareTest({
singleWorker: true,
wrangler: { configPath: './wrangler.toml' },
miniflare: {
workers: [
{
name: '<your-worker-name>',
modules: true,
scriptPath: './<your-worker-name>/index.js',
compatibilityDate: '2024-01-01',
compatibilityFlags: ['nodejs_compat'],
},
],
},
}),
],
});
Secrets
Secrets live in Wrangler vars, not in the repository. Never commit a worker secret, and never deploy from a local machine when a workflow can do it.
Related
-
Testing
The kinds of tests we write, who writes them, and what a good assertion looks like
-
Naming projects
The platform-type-name convention for repositories, Composer packages and npm packages