DEV Community

Cover image for Build blazing fast serverless apps using Cloudflare ๐Ÿƒ
Charles Gรฉry for Serverless By Theodo

Posted on

Build blazing fast serverless apps using Cloudflare ๐Ÿƒ

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.

Fast GIF

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

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"
  }
}
Enter fullscreen mode Exit fullscreen mode

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"]
    }
  }
Enter fullscreen mode Exit fullscreen mode

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': '*',
        },
      }
    );
  },
};
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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.

The KV Tab

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>" }
]
Enter fullscreen mode Exit fullscreen mode

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': '*',
            },
          }
        );
        };
    }};
Enter fullscreen mode Exit fullscreen mode

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 the env 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 ๐Ÿš€ !

Stored quote in KV

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': '*',
        },
      }
    );
Enter fullscreen mode Exit fullscreen mode

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 ๐ŸŽŠ !

Image description

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 !

Top comments (1)

Collapse
 
robinamirbahar profile image
Robina

Good Job