INTEGRITY Cloudflare Docs

Workers API reference

The in-Worker R2 API is accessed by binding an R2 bucket to a Worker. The Worker you write can expose external access to buckets via a route or manipulate R2 objects internally.

The R2 API includes some extensions and semantic differences from the S3 API. If you need S3 compatibility, consider using the S3-compatible API.

Concepts

R2 organizes the data you store, called objects, into containers, called buckets. Buckets are the fundamental unit of performance, scaling, and access within R2.

Create a binding

To bind your R2 bucket to your Worker, add the following to your Wrangler file. Update the binding property to a valid JavaScript variable identifier and bucket_name to the name of your R2 bucket:

{
	"r2_buckets": [
		{
			"binding": "MY_BUCKET", // <~ valid JavaScript variable name
			"bucket_name": "<YOUR_BUCKET_NAME>"
		}
	]
}
[[r2_buckets]]
binding = "MY_BUCKET"
bucket_name = "<YOUR_BUCKET_NAME>"

Within your Worker, your bucket binding is now available under the MY_BUCKET variable and you can begin interacting with it using the bucket methods described below.

Bucket method definitions

The following methods are available on the bucket binding object injected into your code.

For example, to issue a PUT object request using the binding above:

export default {
	async fetch(request, env) {
		const url = new URL(request.url);
		const key = url.pathname.slice(1);

		switch (request.method) {
			case "PUT":
				await env.MY_BUCKET.put(key, request.body);
				return new Response(`Put ${key} successfully!`);

			default:
				return new Response(`${request.method} is not allowed.`, {
					status: 405,
					headers: {
						Allow: "PUT",
					},
				});
		}
	},
};
from workers import WorkerEntrypoint, Response
from urllib.parse import urlparse

class Default(WorkerEntrypoint):
	async def fetch(self, request):
		url = urlparse(request.url)
		key = url.path[1:]

		if request.method == "PUT":
			await self.env.MY_BUCKET.put(key, request.body)
			return Response(f"Put {key} successfully!")
		else:
			return Response(
				f"{request.method} is not allowed.",
				status=405,
				headers={"Allow": "PUT"}
			)

R2Object definition

R2Object is created when you PUT an object into an R2 bucket. R2Object represents the metadata of an object based on the information provided by the uploader. Every object that you PUT into an R2 bucket will have an R2Object created.

R2ObjectBody definition

R2ObjectBody represents an object's metadata combined with its body. It is returned when you GET an object from an R2 bucket. The full list of keys for R2ObjectBody includes the list below and all keys inherited from R2Object.

R2MultipartUpload definition

An R2MultipartUpload object is created when you call createMultipartUpload or resumeMultipartUpload. R2MultipartUpload is a representation of an ongoing multipart upload.

Uncompleted multipart uploads will be automatically aborted after 7 days.

Method-specific types

R2GetOptions

Ranged reads

R2GetOptions accepts a range parameter, which can be used to restrict the data returned in body.

There are 3 variations of arguments that can be used in a range:

R2PutOptions

R2MultipartOptions

R2ListOptions

const options = {
	limit: 500,
	include: ["customMetadata"],
};

const listed = await env.MY_BUCKET.list(options);

let truncated = listed.truncated;
let cursor = truncated ? listed.cursor : undefined;

// ❌ - if your limit can't fit into a single response or your
// bucket has less objects than the limit, it will get stuck here.
while (listed.objects.length < options.limit) {
	// ...
}

// ✅ - use the truncated property to check if there are more
// objects to be returned
while (truncated) {
	const next = await env.MY_BUCKET.list({
		...options,
		cursor: cursor,
	});
	listed.objects.push(...next.objects);

	truncated = next.truncated;
	cursor = next.cursor;
}
limit = 500
include = ["customMetadata"]

listed = await self.env.MY_BUCKET.list(limit=limit, include=include)

truncated = listed.truncated
cursor = listed.cursor if truncated else None

# ❌ - if your limit can't fit into a single response or your
# bucket has less objects than the limit, it will get stuck here.
while len(listed.objects) < limit:
    ...

# ✅ - use the truncated property to check if there are more
# objects to be returned
while truncated:
    next_page = await self.env.MY_BUCKET.list(limit=limit, include=include, cursor=cursor)
    listed.objects.extend(next_page.objects)

    truncated = next_page.truncated
    cursor = next_page.cursor

R2Objects

An object containing an R2Object array, returned by BUCKET_BINDING.list().

Conditional operations

You can pass an R2Conditional object to R2GetOptions and R2PutOptions. If the condition check for get() fails, the body will not be returned. This will make get() have lower latency.

If the condition check for put() fails, null will be returned instead of the R2Object.

Alternatively, you can pass a Headers object containing conditional headers to R2GetOptions and R2PutOptions. For information on these conditional headers, refer to the MDN docs on conditional requests. All conditional headers aside from If-Range are supported.

For more specific information about conditional requests, refer to RFC 7232.

HTTP Metadata

Generally, these fields match the HTTP metadata passed when the object was created. They can be overridden when issuing GET requests, in which case, the given values will be echoed back in the response.

Checksums

If a checksum was provided when using the put() binding, it will be available on the returned object under the checksums property. The MD5 checksum will be included by default for non-multipart objects.

R2UploadedPart

An R2UploadedPart object represents a part that has been uploaded. R2UploadedPart objects are returned from uploadPart operations and must be passed to completeMultipartUpload operations.

Storage Class

The storage class where an R2Object is stored. The available storage classes are Standard and InfrequentAccess. Refer to Storage classes for more information.