new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Cloudflare Workers · all subjects

bindings

223 notes in this subject, read out of this brain and free to use. This is page 4 of 4.

Read R2 file and convert to blob

To read a file from R2 in a Worker, use `c.env.<BINDING_NAME>.get(filename)` to retrieve the R2ObjectBody, then call `.blob()` on it to convert to a Blob object.

Use R2 in Hono middleware

Access R2 buckets in Hono route handlers via the context object: `c.env.<BINDING_NAME>` provides access to the R2 bucket specified in wrangler.toml.

Convert R2 file to OpenAI File object

Import `toFile` from 'openai/uploads' and use `await toFile(blob, filename)` to convert a blob from R2 into a File object compatible with OpenAI API. Then pass this to `openai.files.create({ file, purpose: "fine-tune" })`.

Upload file to R2 with wrangler

Use `npx wrangler r2 object put <PATH> -f <FILE_NAME>` to upload a file to R2. The PATH parameter is the combined bucket and file path (for example, `fine-tune-ai/finetune.jsonl`), and FILE_NAME is the local filename of the file being uploaded.

Real-time chat app architecture with Durable Objects

A real-time chat application can be built using Durable Objects to control each chat room. Users connect to the Durable Object using WebSockets. Messages from one user are broadcast to all other users in the room. Chat history is stored in durable storage, and real-time messages are relayed directly from one user to others without going through the storage layer.

Uninstall chat application by removing Durable Object bindings

To uninstall a chat application that uses Durable Objects, modify the Wrangler file to remove the durable_objects bindings and add a deleted_classes migration. Set durable_objects.bindings to an empty array and add a migration with a deleted_classes array containing the Durable Object class names to be deleted.

Durable Objects migration with deleted_classes

To delete Durable Object classes, add a migration entry to the Wrangler configuration with a unique tag field and a deleted_classes array containing the class names to delete. Each migration tag must be unique. After updating the configuration, run npx wrangler deploy to apply the migration.

Hyperdrive recommended for MySQL connections

Hyperdrive is the recommended approach for connecting to MySQL databases from Cloudflare Workers. It provides optimal performance and ensures secure connectivity between a Worker and a MySQL database. Direct MySQL connections without Hyperdrive are not recommended because MySQL drivers rely on unsupported Node.js APIs to create secure connections, which prevents connections.

Create Hyperdrive configuration command

Use the command `npx wrangler hyperdrive create <NAME_OF_HYPERDRIVE_CONFIG> --connection-string="mysql://user:password@HOSTNAME_OR_IP_ADDRESS:PORT/database_name"` to create a Hyperdrive configuration. The command outputs a Hyperdrive configuration ID that must be added to the Wrangler file as a binding.

Hyperdrive binding configuration in wrangler.jsonc

Add a Hyperdrive binding to wrangler.jsonc with the structure: a `hyperdrive` array containing an object with `binding` (the variable name, typically "HYPERDRIVE") and `id` (the Hyperdrive configuration ID from the create command). The file must also include `compatibility_flags` with `nodejs_compat` enabled.

PostgreSQL connection with pg library setup

To connect to a PostgreSQL database with Cloudflare Workers, install the pg library (node-postgres) version 8.16.3 or higher, and install TypeScript types with @types/pg for type checking and autocompletion. Node.js compatibility must be enabled for database drivers.

Hyperdrive binding configuration in wrangler

Configure Hyperdrive for PostgreSQL acceleration in wrangler.json with: hyperdrive: [{ binding: 'HYPERDRIVE', id: '<ID_OF_CREATED_HYPERDRIVE_CONFIGURATION>' }]. Create the Hyperdrive configuration with: npx wrangler hyperdrive create <NAME> --connection-string='postgres://...' --caching-disabled. Generate types with: npx wrangler types.

R2 bucket binding configuration in wrangler.toml

To configure access to an R2 bucket in a Worker, add an r2_buckets array to the Wrangler configuration file with an object containing a binding name and bucket_name. The binding property specifies the variable name used in the Worker code, and bucket_name specifies the actual R2 bucket name. Example: {"r2_buckets": [{"binding": "MY_BUCKET", "bucket_name": "<YOUR_BUCKET_NAME>"}]}

Fetch files from R2 bucket using get() method

To retrieve a file from an R2 bucket, use the binding's .get(key) method, which returns the object or null if not found. The key is typically derived from the URL pathname. Use object.writeHttpMetadata(headers) to set response headers and object.httpEtag to include the ETag header. Return the response with object.body as the response body.

Upload files to R2 bucket using put() method

To upload a file to an R2 bucket, use the binding's .put(key, data) method where key is the object path and data is the request body or file content. This method performs the upload asynchronously and should be awaited.

Example: fetch file from R2 bucket in Worker

interface Env { MY_BUCKET: R2Bucket; } export default { async fetch(request, env): Promise<Response> { const url = new URL(request.url); const key = url.pathname.slice(1); const object = await env.MY_BUCKET.get(key); if (object === null) { return new Response("Object Not Found", { status: 404 }); } const headers = new Headers(); object.writeHttpMetadata(headers); headers.set("etag", object.httpEtag); return new Response(object.body, { headers, }); }, } satisfies ExportedHandler<Env>;

Example: upload file to R2 bucket with authentication

interface Env { MY_BUCKET: R2Bucket; AUTH_SECRET: string; } export default { async fetch(request, env): Promise<Response> { if (request.method === "PUT") { const auth = request.headers.get("Authorization"); const expectedAuth = `Bearer ${env.AUTH_SECRET}`; if (!auth || auth !== expectedAuth) { return new Response("Unauthorized", { status: 401 }); } const url = new URL(request.url); const key = url.pathname.slice(1); await env.MY_BUCKET.put(key, request.body); return new Response(`Object ${key} uploaded successfully!`); } }, } satisfies ExportedHandler<Env>;

Create R2 bucket with Wrangler CLI

To create an R2 bucket, run the command `npx wrangler r2 bucket create <YOUR_BUCKET_NAME>` from the terminal, replacing `<YOUR_BUCKET_NAME>` with the desired bucket name. To list existing R2 buckets in the account, run `npx wrangler r2 bucket list`.

Write to KV in Rust

Write data to KV in Rust using ctx.kv("binding")?.put(key, value)?.execute().await. The put() method takes a string key and value, and execute().await performs the operation.

Create KV namespace with wrangler

Create a KV namespace using 'npx wrangler kv namespace create <namespace-name>' command. This generates configuration that must be added to the wrangler configuration file.

Access KV namespace in Rust with ctx.kv()

In Rust Workers, access a KV namespace binding using ctx.kv("binding-name") where binding-name matches the binding configured in wrangler.json.

Read from KV in Rust

Read data from KV in Rust using ctx.kv("binding")?.get(key).text().await?. The get() method retrieves the value as text, and returns Option<String> (Some(value) if found, None if not found).

Rust Workers POST route with KV write example

Example of writing to KV in a POST handler: .post_async("/:country", |mut req, ctx| async move { let country = ctx.param("country").unwrap(); let city = match req.json::<Country>().await { Ok(c) => c.city, Err(_) => String::from(""), }; if city.is_empty() { return Response::error("Bad Request", 400); }; return match ctx.kv("cities")?.put(country, &city)?.execute().await { Ok(_) => Response::ok(city), Err(_) => Response::error("Bad Request", 400), }; })

Rust Workers GET route with KV read example

Example of reading from KV in a GET handler: .get_async("/:country", |_req, ctx| async move { if let Some(country) = ctx.param("country") { return match ctx.kv("cities")?.get(country).text().await? { Some(city) => Response::ok(city), None => Response::error("Country not found", 404), }; } Response::error("Bad Request", 400) })

Service bindings do not create new versions on dependency changes

New versions are not created when you make changes to resources connected to your Worker through service bindings. For example, if Worker A and Worker B are connected via a service binding, changing the code of Worker B will not create a new version of Worker A. However, changes to the service binding configuration on Worker A will not create a new version of Worker B.

Version metadata binding accesses version information at runtime

Use the Version metadata binding to access version ID or version tag in your Worker at runtime.

Rollback blocked if Durable Object class changed

You cannot roll back to a previous version of your Worker if a Durable Object class lifecycle change has occurred between the version in the active deployment and the version selected to roll back to. A class lifecycle change includes changes via exports or the legacy migrations array.

Rollback blocked if binding resource deleted

You cannot roll back to a previous version of your Worker if the target deployment has a binding to an R2 bucket, KV namespace, or queue that no longer exists.

Bindings not changed during rollback

Resources connected to your Worker through bindings will not be changed during a rollback. This can cause errors if the code for a prior version references data structures that have changed between versions.

Version overrides with service bindings via fetch

When making a subrequest from one Worker to another using a service binding, you can set the `Cloudflare-Workers-Version-Overrides` header to test a specific version of a downstream Worker. If you forward the original request object, the override header carries through automatically. Alternatively, you can set an override header explicitly in the fetch options.

Service binding fetch example with version override

Example of setting a version override header explicitly when calling a service binding: export default { async fetch(request: Request, env: Env): Promise<Response> { const response = await env.MY_SERVICE.fetch("https://example.com/", { headers: { "Cloudflare-Workers-Version-Overrides": 'my-downstream-worker="dc8dcd28-271b-4367-9840-6c244f84cb40"', }, }); return response; }, };

Service binding fetch forwards version override automatically

When forwarding the original request object in a service binding fetch call, the override header from the inbound request carries through automatically to the downstream Worker. export default { async fetch(request: Request, env: Env): Promise<Response> { return env.MY_SERVICE.fetch(request); }, };

Version overrides not supported with RPC service bindings

Version overrides only apply to fetch()-based service binding calls. There is currently no way to specify version overrides when calling a service binding via RPC (env.MY_SERVICE.someMethod()) because RPC calls do not support attaching headers.

PluginConfig.remoteBindings field

remoteBindings is an optional boolean field that controls whether remote bindings should be enabled. It defaults to true.

AI Gateway Worker binding methods available

Cloudflare Workers can now connect to AI Gateway directly using new Worker binding methods. These methods simplify integration by eliminating the need to use the REST API and manually authenticate.

AI Gateway binding patchLog method

The patchLog method allows you to send feedback and update metadata for AI Gateway logs from within a Worker.

AI Gateway binding getLog method

The getLog method retrieves detailed log information from AI Gateway for requests made through a Worker binding.

AI Gateway binding run method

The run method executes universal requests to any AI Gateway provider from a Worker, allowing you to send requests to AI services behind your AI Gateway configurations.

D1 prepared statement API with bind and all methods

D1 provides prepare(), bind(), and all() methods for database queries. prepare(sql) creates a prepared statement, bind(...values) binds parameter values, and all() returns { results } containing query results. Example: const { results } = await env.DB.prepare('SELECT * FROM members WHERE id = ?').bind(id).all()

D1 INSERT operation returns success status and last_row_id

When executing an INSERT statement with D1, the result object includes a success field (boolean) and result.meta.last_row_id containing the ID of the inserted row.

D1 UPDATE operation returns changes count

When executing an UPDATE statement with D1, the result object includes result.meta.changes indicating the number of rows affected by the update.

D1 DELETE operation returns changes count

When executing a DELETE statement with D1, the result object includes result.meta.changes indicating the number of rows deleted.

D1 UNIQUE constraint violation error handling

When a UNIQUE constraint is violated in D1, the error message includes 'UNIQUE constraint failed'. Catch this error to handle duplicate entries (e.g., duplicate email addresses) and return appropriate HTTP status codes like 409 Conflict.

Give your agent this brain