Deploy your first Serverless function in 5 minutes with Cloudflare Workers

cloud-sunset

Photo by AYLİN GÖRAL

Serverless is one hot topic in the dev world especially during the last couple of years. As per the name suggests, Serverless is a way of deploying endpoints aka functions without having to deal with the server or hardware they run on.

Not having to worry about servers makes it a really cost effective model as it we only pay for the time our functions are being executed. If our APIs only run for e.g 30 hours per month then we are going to pay only for these 30 hours instead of the time where the server sits idle which is 24 hours per day for the whole month.

Apart from the cost benefits, Serverless also makes it easy for us to deal with peak traffic with its auto scaling model. These are really good reasons for us to start using Serverless ASAP.

Signup for Cloudflare Workers

You can go and sign up at https://workers.cloudflare.com/. Their generous free tier provides us with 100,000 read operations per day!!! I don't know about you, but for me this number is a lot more than enough for my side projects.

I mean even if you want to use their paid plan it's $5 for 1,000,000 requests per month. Choose whichever plan works for you and then let's go and write some code.

Installing the CLI tools

Now that we have an account first thing to do is to install the CLI tools. For this example we are going to use the JS client. Let's install wrangler globally.

npm install -g @cloudflare/wrangler

Now that we have wrangler installed, we can see that it provides us with a number of things we can do with it. Now let's login to our account

wrangler login
Allow Wrangler to open a page in your browser? [y/n]

Typing y will open a window in our browser.

cloudflare-authorize

Once we authorize wrangler to manage our function, the waiting for API token... message should disappear from our CLI. Then the following message should confirm that we have successfully logged in.

wrangler whoami

+--------------------------------+-----------------------------------+
| Account Name                   | Account ID                        |
+--------------------------------+-----------------------------------+
| your_email@gmail.com's Account | do_not_share_this_key_with_anyone |
+--------------------------------+-----------------------------------+

If like me you had problems making that to work, an alternative way to do that to do that manually. Go to https://dash.cloudflare.com/profile/api-tokens and check the Global API key. Once we put our password and go through the CAPTCHA we can copy the api key. Then let's configure that in wrangler.

wrangler config --api-key
We don't recommend using your Global API Key!
Please consider using an API Token instead.

https://support.cloudflare.com/hc/en-us/articles/200167836-Managing-API-Tokens-and-Keys
Enter Email:
your_email@gmail.com
Enter Global API Key:
do_not_share_this_key_with_anyone
💁  Validating credentials...
✨  Successfully configured. You can find your configuration file at: /Users/your_username/.wrangler/config/default.toml

In case you keep having troubles, check the link they recommend https://support.cloudflare.com/hc/en-us/articles/200167836-Managing-API-Tokens-and-Keys

Our wrangler whoami command should now show us that we are logged in. Now time to generate a new project. You can check the starters page in the Cloudflare Workers docs which has plenty of projects to use as a starting point. For this blog post I will make a really simple function that prints the number of repositories a user has on Github.

wrangler generate username_github_repos

Now time for the cool stuff! 🎉

The JS Code

Now that the project is generated let's open it with our favourite text editor (in my case VSCode) and see the code. The index file will contain the following.

/**
 * Respond with "Username x has y repos" text
 * @param {Request} request
 */
async function handleRequest (request) {
  try {
    let username = "harrisgeo88"

    // splits the url from the query string
    const querystring = request.url.split("?")[1]

    if (querystring) {
      // we split the query string into an array
      const params = querystring.split("&")

      // we search for username
      const userParam = params.find(y => y.includes("username"))

      // if username exists then use it. Otherwise use the default
      if (userParam) {
        username = userParam.split("=")[1]
      }
    }

    const response = await fetch(
      `https://api.github.com/users/${username}/repos?per_page=100`,
      {
        headers: {
          "User-Agent": "request",
        },
      }
    )

    const allRepos = await response.json()
    const length = allRepos.length

    let repos = ""
    if (length > 99) {
      repos = "more than 100"
    } else if (!length) {
      repos = "0"
    } else {
      repos = `${length}`
    }

    return new Response(`Username ${username} has ${repos} repos`, {
      headers: { "content-type": "text/plain" },
    })
  } catch (err) {
    console.log(err)
  }
}

addEventListener("fetch", event => {
  event.respondWith(handleRequest(event.request))
})

Just to keep things simple in this blog post, I am not using any 3rd party libraries. For that reason the query string params part is done manually. Libraries like qs would make that job easier.

What this code does is it takes the username query param we pass and uses it to fetch the repos for that user. The Github API is limited to 100 results per page. In case your username has more than 100 results, the page will print Username x has more than 100 repos.

If we do not pass any query params, it will default to my username harrisgeo88. Please keep in mind that this api returns only your public repos. In case you get confused like me and start wondering why the numbers don't match the ones on my profile when I am logged in, it's because of that 😂.

Now that our function is ready, let's run it locally and see our code in action.

Running locally

The wrangler command will do the job for us and run the server locally.

wrangler dev

If this is the first time you're running this project, you will notice that the CLI will throw the following error. Error: field account_id is required to deploy to workers.dev. Thankfully that is really easy to solve. If we open our editor, we will see a file called wrangler.toml. This is the config file and it looks like this

name = "username_github_repos"
type = "javascript"
account_id = ""
workers_dev = true
route = ""
zone_id = ""

Remember earlier when we ran wrangler whoami? Let's do that again and copy the Account ID field that was printed there. That is what we need to paste into the account_id of the wrangler.toml file. Once we do that, save the file and run again wrangler dev, we will see the following.

wrangler dev
💁  watching "./"
👂  Listening on http://127.0.0.1:8787

Now clicking on that url is going to open the browser and will show you my username and number of repos I have. This is the default state though. Replace johnsmith with your username in ?username=johnsmith. This will give us http://127.0.0.1:8787/?username=johnsmith

Awesome! Now let's deploy that function.

Deploying our function

Once again wrangler will do that for us.

wrangler publish

Hopefully you will see the following.

wrangler publish
✨  JavaScript project found. Skipping unnecessary build!
✨  Successfully published your script to
 https://username_github_repos.harrisgeo.workers.dev

Aaaand that's it. You can view mine right here https://usernamegithubrepos.harrisgeo.workers.dev

Yes that was it!

Congratulations!!! You just deployed your first Cloudflare Worker function to the cloud. I really like how simple they have made it to get started with it. It totally is a free, simple and generally awesome way to start publishing more side projects to the cloud without having to worry about contract, servers and all that kind of stuff.

The code in the blog post can be found here

What project are you going to build with Cloudflare Workers?

Subscribe and get notified