www/src/content/docs/docs/start/cloudflare/worker.mdx
We are going to build an API with a Cloudflare Worker, add an R2 bucket for file uploads, and deploy it using SST.
:::tip[View source] You can view the source of this example in our repo. :::
Before you get started, create your Cloudflare API token.
Let's start by creating our app.
mkdir my-worker && cd my-worker
npm init -y
Now let's initialize SST in our app.
npx sst@latest init
npm install
Select the defaults and pick Cloudflare. This'll create a sst.config.ts file in your project root.
Set the token and account ID in your shell or .env file.
export CLOUDFLARE_API_TOKEN=aaaaaaaa_aaaaaaaaaaaa_aaaaaaaa
export CLOUDFLARE_DEFAULT_ACCOUNT_ID=aaaaaaaa_aaaaaaaaaaaa_aaaaaaaa
Let's add a Worker. Update your sst.config.ts.
async run() {
const worker = new sst.cloudflare.Worker("MyWorker", {
handler: "./index.ts",
url: true,
});
return {
api: worker.url,
};
}
We are enabling the Worker URL, so we can use it as our API.
Let's add an R2 bucket for file uploads. Update your sst.config.ts.
const bucket = new sst.cloudflare.Bucket("MyBucket");
Add this above the Worker component.
Now, link the bucket to our Worker.
const worker = new sst.cloudflare.Worker("MyWorker", {
handler: "./index.ts",
link: [bucket],
url: true,
});
We want our API to upload a file to the R2 bucket if you make a PUT request to it. Create an index.ts file and add the following.
export default {
async fetch(req: Request) {
if (req.method == "PUT") {
const key = crypto.randomUUID();
await Resource.MyBucket.put(key, req.body, {
httpMetadata: {
contentType: req.headers.get("content-type"),
},
});
return new Response(`Object created with key: ${key}`);
}
},
};
:::tip
We are uploading to our R2 bucket with the SDK — Resource.MyBucket.put()
:::
Import the SDK.
import { Resource } from "sst";
We want to download the last uploaded file if you make a GET request to the API. Add this to the fetch function in your index.ts file.
if (req.method == "GET") {
const first = await Resource.MyBucket.list().then(
(res) =>
res.objects.toSorted(
(a, b) => a.uploaded.getTime() - b.uploaded.getTime(),
)[0],
);
const result = await Resource.MyBucket.get(first.key);
return new Response(result.body, {
headers: {
"content-type": result.httpMetadata.contentType,
},
});
}
We are getting a list of the files in the files in the bucket with Resource.MyBucket.list() and we are getting a file for the given key with Resource.MyBucket.get().
Start your app in dev mode.
npx sst dev
This will give you the URL of your API.
+ Complete
api: https://start-cloudflare-jayair-myworkerscript.sst-15d.workers.dev
Let's try uploading a file from your project root. Make sure to use your API URL.
curl --upload-file package.json https://start-cloudflare-jayair-myworkerscript.sst-15d.workers.dev
Now head over to https://start-cloudflare-jayair-myworkerscript.sst-15d.workers.dev in your browser and it'll load the file you just uploaded.
Finally, let's deploy your app!
npx sst deploy --stage production
You can use any stage name here but it's good to create a new stage for production.