DEV Community

Cover image for Deploy your first Serverless function in 5 minutes with Cloudflare Workers

Deploy your first Serverless function in 5 minutes with Cloudflare Workers

Originally posted on my blog harrisgeo.me

https://user-images.githubusercontent.com/630705/102919879-89e6b400-4481-11eb-99ae-05dc6dd7866e.jpg

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

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

Typing y will open a window in our browser.

https://user-images.githubusercontent.com/630705/102906153-230ad000-446c-11eb-8d5a-bbfff6cf56d4.png

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

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

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

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

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

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

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

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

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

Aaaand that's it. You can view mine right here https://username_github_repos.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 an 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?

Please subscribe to my newsletter if you enjoyed this post and you would like to get notified when new ones come out.

Top comments (5)

Collapse
 
oguimbal profile image
Olivier Guimbal • Edited

I'm a fan of CF workers. However, I'd add that it's important to understand several things:

1) They're not Nodejs. They're actually kind of webworkers (they're implemented as v8 isolates like webworkers).
Meaning that you cant execute multiple js files (you must bundle them), you cant require node libs, or use node apis. That's a huge limitation.

2) Maybe it has changed, but I think they're limited to 50ms of actual CPU computation. Which is more than enough to do many things, but there is no way to perform heavy computations with that.

3) They're a REALLY fast. You get near zero cold starts (instead of ~100-300ms for an aws lambda running nodejs)

4) They run on the edge, which is sooo cool. You get the same performance everywhere in the world.

Collapse
 
harrisgeo88 profile image
Harris Geo πŸ‘¨πŸ»β€πŸ’»

Oh thanks for the extra info. I have to admit that I wasn’t aware of some of these details.

I don’t think that the intention in this blog is to tell people to switch their production apis to Cloudflare workers.

It’s more like how to get started playing with Serverless on your side projects.

Collapse
 
oguimbal profile image
Olivier Guimbal

I get that 😊. I just felt it was worth mentioning as a side note !

Collapse
 
kayis profile image
K

Didn't Workers Unlimited solve that CPU time restriction?

Collapse
 
oguimbal profile image
Olivier Guimbal

I guess it has, you seem to know better. I haven't checked for a while (thus my "maybe it has changed"). Thanks for the info