Originally posted on my blog harrisgeo.me
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.
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 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
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://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)
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.
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.
I get that π. I just felt it was worth mentioning as a side note !
Didn't Workers Unlimited solve that CPU time restriction?
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