Hi.
I’m a little new to workers, and I’m trying to understand a few things.
I have an application on the iOS App Store, and I want to provide some content to the user of my app, where each file is downloaded at various points in the app (think levels of a game).
I’ve settled on the approach of storing the content in an R2 bucket, and then having a basic API written in a worker that takes a download request and returns the object in the bucket.
The worker defines two endpoints:
files
This returns a JSON response listing the files that are associated with a specific identifier. For example, given an identifier of “level1”, will return a list of assets such as 3D models and textures that need downloading.
The basic flow of the worker is:
- Check if the Authorization header is valid.
- Read an identifier from the
URLSearchParams
. - Read a JSON file that has the list of downloads for an identifier (ideally from R2).
- Find the downloads in the JSON for the specified identifier.
- If the download is marked as premium, call the Apple App Store API to check if the user has a subscription to the app (the App Store receipt is provided in the header).
- Return a new JSON response containing a list of files read from the JSON for the specified identifier.
download
This takes one of the files returned from the files
endpoint and sends the file back from R2 to the user. It must also check if the file is premium, and confirm the user can download the file by checking if the user has a subscription with apple.
The basic flow of the worker is:
- Check if the Authorization header is valid.
- Read an identifier from the
URLSearchParams
. - Read a JSON file that has the list of downloads (ideally from R2).
- Find the download in the JSON for the specified identifier.
- If the download is marked as premium, call the Apple App Store API to check if the user has a subscription to the app (the App Store receipt is provided in the header).
- Get the file from the R2 bucket, and return to the user in the Response.
My questions are:
- Can I store the JSON files describing valid identifiers in R2 and parse the data in the worker? Or should I be using KV storage?
- Am I going to run into issues with Cloudflare using this method? I saw comments on the forum about not using the workers for running a FileLocker, and whilst I’m using this to serve up R2 files for my app (not that many), I worry about infringing on some policy just using it for downloads.
- Finally (and this is my greatest cause for confusion), am I going to be running into double the bandwidth? For example, if a user downloads a file from the worker, does the worker download the file from R2 and then the user downloads it from the worker, or does it simply redirect the user so they’re directly downloading it from R2? If the worker is downloading the file from R2, is the worker likely to time out, run out of memory or have high bandwidth charges?
The code for downloading is as follows (let me know if I should share the entire worker):
// Get the object from the object store.
//
const object = await env.CONTENT.get(identifier);
if(object === null) {
return generateResponse(404, "The provided object cannot be found.")
}
// Generate the API response and return the object.
//
const headers = new Headers();
object.writeHttpMetadata(headers);
headers.set("e-tag", object.httpEtag);
return new Response(object.body, { status: 200, headers });
Does the get
method on R2Bucket
actually download the body in the worker, or is it just passing it along to the caller of the worker? If that makes sense - as I said, I’m new to this.
Thanks
-Matt