Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

R2 Fields

Cloudflare R2 is a globally distributed object storage service that allows you to store and serve large amounts of unstructured data, such as images, videos, and other media files. With Cloesce, you can easily integrate R2 into your application by defining R2 fields in your Models.

Many of the same concepts and syntax for defining KV fields in Cloesce also apply to R2 fields. Read the KV fields chapter for more information.

Defining an Environment Binding

To use R2 fields in your Models, you first need to define an environment binding for the R2 bucket in your Cloesce schema:

r2 MyBucket {
    // ...templates
    image(key: string) {
        "images/{key}"
    }
}

Unlike KV fields, no specific type is necessary for an R2 field declaration, as the actual value is never queried and buffered into memory in the application layer.

Read more about R2 bindings in the Environment chapter.

Defining an R2 Field

Note

R2 is used to store large unstructured data. For this reason, Cloesce will not query and buffer the full value of an R2 field into the worker runtime. Instead, only a HEAD request is made to R2 to check for existence and retrieve metadata.

A field in a Model may reference an R2 bindings template to define an R2 field:

r2 MyBucket {
    // ...templates
    image(key: string) {
        "images/{key}"
    }
}

model Image {
    route {
        id: string
    }

    r2 MyBucket::image(id) {
        my_image
    }
}

The above snippet defines a Model Image with an R2 field my_image that is stored in the bucket MyBucket under the key “images/{id}”, where {id} is a placeholder that will be replaced with the actual value of the id route field when accessing R2.

See information about route fields in the KV fields chapter.

Generated Types

Backend

Since Cloesce does not fetch the actual value of an R2 field into the application layer, the Cloudflare standard R2ObjectBody type is used for all R2 fields in the generated backend code.

Each R2 Bucket will also generate a corresponding namespace with helper functions template, get, put, and list, with similar signatures to the KV helper functions generated for KV namespaces.

Frontend

It is possible to serialize the r2object type (or a Model field under the r2 block).

Cloesce will send a subset of the full R2 HEAD response metadata back to the frontend, including the key, version, size, etag, httpEtag, uploaded timestamp, and any custom metadata defined on the R2 object. This allows you to work with R2 objects in the frontend without having to fetch the full object data.

export interface R2Object {
  key: string;
  version: string;
  size: number;
  etag: string;
  httpEtag: string;
  uploaded: Date;
  customMetadata?: Record<string, string>;
}