Build blazing fast serverless apps using Cloudflare 🏃
Charles Géry
Posted on October 5, 2023
TL;DR
⚡Build a blazing fast Cloudflare worker that stores, and return random quotes.
Intro
Do you like speed? 🏃 Do you like simplicity?Then, Cloudflare Workers might be the solution for your next application.
Cloudflare is a cloud-provider, most-known for their CDN, offering several services to build cloud applications. Among them, Cloudflare Workers is a serverless service that allows you to run serverless functions at edge (like Lambda@Edge if you are an AWS user). This means that your code runs closer to end-users, resulting in blazing fast response times.
Disclaimer: In my opinion Cloudflare Workers are best suited to small projets. I haven't found satisfying tools to deploy and manage several Cloudflare Workers on big projects. In that situation, a service like AWS Lambda is probably more suited.
That being said, Cloudflare Workers are super easy to setup and offer a great DevX if you want to deploy simple applications.
To show you that, we are going to build a simple worker, that allows you to save quotes in a key-value store, and return random quotes among the ones you saved.
Creating your first worker 🥇
Prerequisites
- A Cloudflare account (it is super easy to setup)
First create a new folder where your projet will reside. Inside this folder, you can add a package.json
file:
{
"name": "awesome-quotes-service",
"devDependencies": {
"@cloudflare/workers-types": "^4.20230801.0",
"typescript": "^5.1.6",
"wrangler": "^3.3.0"
}
}
We will be using Typescript, so you can also add a tsconfig.json
file with your TS configuration:
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"lib": ["esnext"],
"preserveSymlinks": true,
"types": ["@cloudflare/workers-types"]
}
}
Then you can create an index.ts
file that will contain the code of our function:
export default {
async fetch(
request: Request,
env: Env,
): Promise<Response> {
return new Response(
JSON.stringify('Hello from my first Cloudflare Worker'),
{
// Headers configuration of API response
headers: {
'content-type': 'application/json',
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Origin': '*',
},
}
);
},
};
In this file, we are creating a fetch
function that contains our Cloudflare Worker code. It takes as an input:
- A
request
variable containing your request data (eg. body, url, method etc…), - An
env
variable, that contains the binding associated to your worker (more of that later…)
Inside it, we return a Response
object that contains two parameters:
- The body of your response,
- Some response configuration, here our response headers
Finally, you can create a wrangler.toml
file. Wrangler is a command-line tool developed by Cloudflare that is used for building, deploying, and managing Cloudflare Workers. We are going to use it here to configure our worker, and deploy it using the CLI.
// Name of your Cloudflare Worker
name = "quotes"
// A date which will be used to determine which version of the Workers runtime is used.
compatibility_date = "2023-07-21"
After installing your project dependencies using your favorite package manager, you can run npx wrangler deploy ./index.ts
to tell Wrangler to deploy your worker to Cloudflare.
Congratulations 🎉, you just deployed your first worker 💪 ! The url where it is available should be displayed in your terminal. You should see our 'Hello from my first Cloudflare Worker' if you call this url.
Going further
Now that we have a working worker 😲 we are going to take things one step further and add some storage to build our quotes service. For that we are going to use KV. KV is a distributed and highly scalable key-value data store offered by Cloudflare.
We’ll first need to set it up inside Cloudflare’s dashboard before using it in our worker. For that you can go to the KV
tab once connected to your Cloudflare account, and select Create a namespace
that you will call quotes
.
Now that we have a KV store we will be able to store, and retrieve random quotes in it. Let’s start by updating our worker to store quotes. We are going to add a /create
HTTP route, that you can call with a quote to save it in KV.
We first need to update our wrangler.toml
to define a binding with the quotes
KV store to be able to refer it inside our code. You will need the id of your quotes
KV store that you can find on the Cloudflare dashboard.
name = "quotes"
compatibility_date = "2023-07-21"
kv_namespaces = [
{ binding = "quotes", id = "<Copy the ID of your KV Store>" }
]
Then, we will update our worker with the code to store data in the KV store:
export interface Env {
quotes: KVNamespace;
}
export default {
async fetch(
request: Request,
env: Env
): Promise<Response> {
let url = new URL(request.url);
switch (url.pathname) {
case '/create':
// We generate a random key for your quote
const id = crypto.randomUUID();
// We retrieve the quote you pass in your request body
const quote = (await request.json() as any).quote;
// We store your quote in the KV Store
await env.quotes.put(
id,
quote
);
return new Response(
JSON.stringify('Success'),
{
headers: {
'content-type': 'application/json',
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Origin': '*',
},
}
);
};
}};
You can notice several things:
- We added an interface that refers to our
quotes
KV store. This allows us to directly interact with the store through theenv
parameter of the worker. - We are retrieving the body of the request using
request.json()
- We store the quote in KV using the
put
function, that takes a key and a value as parameters.
If you redeploy your worker using wrangler
, call it with a POST request on the /create
route, and a JSON payload containing a quote
parameter, you should be able to store quotes in your KV store. You can check in your Cloudflare dashboard that it is indeed working 🚀 !
Retrieving random quotes
To wrap things up, we need to be able to retrieve random quotes from our worker. Let’s do that ! We will add a new /get
route, that will return a random quote from our KV store. Just add a new case
in the switch
:
case '/get':
// We retrieve all the quotes keys
const quotesKeys = (await env.quotes.list()).keys.map((key) => key.name);
// We pick a random key, and retrieve it from the KV Store
const randomId = quotesKeys[Math.floor(Math.random() * quotesKeys.length)]
const randomQuote = await env.quotes.get(randomId, 'text');
return new Response(
randomQuote,
{
headers: {
'content-type': 'application/json',
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Origin': '*',
},
}
);
In this code we are:
- Listing all the keys of our quotes stored in the KV store using the
list()
function, - We are getting a quote from the KV store using the
get()
function
If you redeploy your Cloudflare Worker you should now be able to call the HTTP GET /get
endpoint to retrieve a random quote 🎊 !
Conclusion
Congratulations, you just created a worker to store and return random quotes ! If you want to push things further, you can plug a Slack bot on it for instance.
I hope you liked this article, don’t hesitate to ask the questions you have in the comments !
Posted on October 5, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.