Create the GET endpoint

Import the APIRoute type from "astro" and create a GET endpoint that accepts the locals parameter.

This endpoint will serve individual files from the bucket based on the file key provided in the URL query parameters.

Get the file key from the request

Extract the file key from the URL query parameters using url.searchParams.get("key"). The key represents the file name or path within the bucket.

Validate that a key is provided - if missing, return a 400 Bad Request error with a descriptive message to help with debugging.

Retrieve the object from the bucket

Access the CLOUD_FILES binding and use the .get() method to retrieve the specific file from the bucket using the provided key.

The method returns an R2Object if the file exists, or null if not found.

Key concepts:

  • Bucket access: The CLOUD_FILES binding provides direct access to the bucket
  • Object retrieval: The .get() method is the primary way to fetch individual files

Extract data and metadata from the object

Convert the R2Object to a usable format using the .arrayBuffer() method, which returns the file data as a Uint8Array. Extract the content type from the object's httpMetadata property, with a fallback to an empty string if not available.

Return the file with proper headers

Create a new Response object with the file data and set the Content-Type header to match the file's content type. This ensures browsers and clients can properly handle the file based on its type.

asset.ts
ExpandClose
1
import type { APIRoute } from "astro";
2

3
export const GET: APIRoute = async ({ request, locals }) => {
4
// Get the key from the request
5
const url = new URL(request.url);
6
const key = url.searchParams.get("key");
7
if (!key) {
8
return new Response("Missing key", { status: 400 });
9
}
10

11
// Get the object from the bucket
12
const bucket = locals.runtime.env.CLOUD_FILES;
13
const object = await bucket.get(key as string);
14
if (!object) {
15
return new Response("Not found", { status: 404 });
16
}
17

18
// Get the data from the object and return it
19
const data = await object.arrayBuffer();
20
const contentType = object.httpMetadata?.contentType ?? "";
21

22
return new Response(data, {
23
headers: {
24
"Content-Type": contentType,
25
},
26
});
27
};