Of course, you might not see these speed improvements in serverless functions. That said serverless functions are usually small pieces of code which perform a single small task. To me that makes them a great choice for learning Rust. You can invest small chunks of your time on focussed code, starting with a simple Rust Cloudflare Worker. Then either as the initial functions evolve and require more sophisticated solutions or, indeed as you consider solving other more detailed problems using Workers, you gradually improve your Rust understanding.
I should point out I am still relatively new to Rust so you might know of better Rust implementations of the Rust code below. In fact, I would love feedback on how I could improve the Rust code (drop comments below or add pull requests to the demo code repo ). Instead of best practice Rust, this is more of a guide on how to get up and running with Rust Cloudflare Workers where I share some of the Rust I have learned. That said I hope you can benefit from the post if you already know Rust but want to know how to get going with Rust Cloudflare Workers.
If you are learning Rust, here are some free resources you might find useful:
- The Rust Programming Language book — normally just referred to as “The Book” is probably the best starting point. Available online as a number of chapters which offer a gentle introduction to Rust. Also try Rust by Example to help push home concepts in the Book, especially if you prefer a more hands-on approach to learning,
- Rustlings — a collection of small exercises you can run through to improve your Rust. Consider this if you prefer a more practical approach to learning, rather than reading the book,
- Rust Cookbook — you will probably use this differently to the other two resources. Rather than work through from start to finish, it is quite handy to dive in to a particular area you need for a problem you are looking at, which you have not yet seen in Rust.
If you prefer videos, Chris Biscardi is behind Rust Adventures which provides another avenue to learning Rust. You can access much of the content for free. Chris is very knowledgable in Rust and I have picked up quite a bit from his blog posts.
Often you need to send out an alert from a serverless function when a certain event occurs. To help out we generate a test email message using SendGrid from our worker. Even when you don’t need to send a message from your worker, you will often need to interact with external services (such as databases), making REST calls. We use Reqwest in our serverless function to send the email. So, even if you don’t need to send email in your first Rust Cloudflare worker, you will have some example code for making REST requests.
You can set up Rust with Homebrew or other package managers. Rust’s recommended approach though, is to install from the Terminal from their script:
This installs rustup which manages your Rust installation. As examples, to update rustup itself and your Rust tooling you would use the following commands:
Cargo is the Rust package manager. To search for crates (Rust packages) try https://crates.io/ . We won’t go into more detail on rustup and cargo here as you will probably find more complete information wherever you are learning Rust.
You need a Cloudflare account to start; sign up for Cloudflare
if you don’t yet have one. Next, set up the
wrangler CLI tool.
You can skip this if you already have
wrangler installed globally via
If you do need to set up
wrangler, the easiest way to do so is
using Rust’s cargo package manager:
This installs the latest available version of
wrangler. To update
wrangler later, just run the same command. If a newer version is available Cargo will update, otherwise,
it just tells you the package is already installed.
Note that Cargo installs
wrangler to the current user’s profile
~/.cargo/bin/wrangler), so you do not need admin privileges.
Rustup should have added the
~/.cargo/bin directory to your Terminal
PATH environment variable. To check this, type
wrangler --version in the Terminal. If all is well you should get the something like
wrangler 1.19.11 as output. If you don’t, you might need to add the directory to your
Next we use
wrangler to create the project boiler plate:
This creates a
wrangler.toml file which contains project config. You
can define variables for use in the Rust code here. As an example
WORKERS_RS_VERSION is defined in line
Do not store secrets (like API keys) here, we will see how to define those in a moment.
Another file which
wrangler has generated in the project is the usual
Currently wrangler does not automatically include the last three lines shown, but you may like to include them to follow best practice (customising to suit your needs).
Fire up the dev environment (with the skeleton code) from the Terminal:
It will take a moment to build the worker the first time you run it. Once the dev environment is
ready to receive requests the Terminal will have the message
Listening on http://127.0.0.1:8787.
In production, typically the worker will be invoked by a REST
PUT request sent to its production address. In development, we can
curl requests to the address above. The boilerplate project includes
some code we can use to test the worker. In your browser go to
http://127.0.0.1:8787/worker-version alternatively, send a
GET request using
curl from the Terminal (in a separate tab):
If all is well you will get a response with the worker version (this is the value defined in
wrangler.toml which we mentioned earlier).
To store a secret API key, we will need to connect our local project to our Cloudflare account. To do this, just type the following command from within the project directory:
wrangler will prompt asking if it can open a page in your browser.
To proceed accept this and
wrangler opens your default browser. You
need to log into your Cloudflare account to authorise
you prefer to use a browser other than your default browser, this is also possible. Just paste the
wrangler prints in the Terminal from there to your preferred browser.
Follow instructions in the Cloudflare console to proceed.
We will use SendGrid to send a test email in a moment. For this to work, we need to make our
SendGrid API key available to the
wrangler environment. We can do this
from the Terminal:
Paste in your SendGrid API key when wrangler prompts and it will store it in the Cloudflare environment. You can access the value both in local development and production.
If you are working with a service other than, SendGrid, just change the name to one that makes
sense and add any additional secrets your service may require with additional
wrangler secret put commands.
As a final step we will add some Rust code to send a test email. We use the SendGrid REST API so
you see how to do this. The crate we use for making REST calls is Reqwest. This performs exactly
the function we would use
(contraction of serialise, deserialise) to create the JSON message data sent to the SendGrid API.
Add the Reqwest and Serde crates in
Cargo.toml to make them available
to our code:
In a moment we will add a
sendgrid_client module. For now let’s
just declare it in
Then we will add a new route to listen on. The worker will send an email when it receives a
GET request on the
Change the email addresses to ones linked to your SendGrid account and which make sense for you.
Notice how you can use the secret we previously defined (line
The SendGrid API expects our email in JSON format and we use
to help us form this. Below is the JSON format SendGrid expects. If you are using a different email
service you will need to tinker with the SendGrid Module to make it work.
Finally add this SendGrid module code to send messages (create the new
With this example, you see a way to send a PUT request with JSON body using Reqwest. We send the
API key as a Bearer Authorization header (formed in lines
58). We could write the JSON body as a
raw string, but defining the structs and using
serde to serialise adds
a little checking.
You can also use serde to deserialise. As an example you could do this if your worker is listening
for a PUT request with a JSON body. In this case
serde helps us convert
the JSON body to Rust structs which we can manipulate in the code.
The SendGrid API expects a
type field on
content entries. However
type is a reserved keyword in Rust so to escape
it, in lines
65, we use
r#type. We can use
console_log for debugging with Rust Cloudflare Workers
like we would use
82. For that to
work, we need the
use directive in line
The test we use here is a little rudimentary. You might already know that Rust lets you define
unit tests within source files. For testing code which calls external APIs (like the SendGrid call
in our code) there are a few crates you can use. I have got on well with the
httptest crate in the past. It works with async code and lets you check the data which your code sends and
mock the response. We won’t look at it here otherwise the post will get too long. Just wanted
to make sure you knew such packages exist!
To test either open
https://127.0.0.1:8787/test-email in your browser
curl (like we did earlier):
Check your inbox. Fingers crossed, you’ll have the test email.
The final step, once you are happy everything is working, is to publish the worker to production:
wrangler will let you know the public url for the worker. Of course,
you can also customise this in the Cloudflare console.
We have learned all about getting started with Rust Cloudflare Workers in this post. More specifically, we have seen:
- a way to send email using a REST API from Rust Cloudflare Workers using Reqwest to POST a JSON body,
- how to store and make secrets and environment variables accessible to Rust Cloudflare Workers,
how you can add debug
console_logmessage to you Cloudflare Worker.
I hope you found this article useful and am keen to hear where you will go next as well as potential improvements, both to the Rust code and explanations above.
- Before getting started with Rust Cloudflare Workers, you need to have the Rust toolchain (rustup) set up on your machine. You will also need a Cloudflare account (which is free to sign up for). With those preliminaries out of the way, use the wrangler generate --type=rust my-project-name command from the Terminal. This will initialise your new project. Finally use the cd command to change into the new project directory (created by wrangler) which will match the project name. You can run wrangler dev to spin up a test server. The project will include the wrangler config in wrangler.toml, project config in Cargo.toml and some skeleton Rust code in the src directory.
- Cloudflare lets you set up secrets or environment variables which you can use in local development as well as in production. You can set the secrets from the command line using wrangler. For it to work though, you first need to link your Rust Cloudflare workers project to your Cloudflare account. Do this by running wrangler login and pasting the output link into the browser in which you are already logged into your Cloudflare account. This is a piece of one-off setup. Now, any time you want to add a new secret to you Rust Cloudflare Workers project just run the wrangler secret put SECRET_NAME command and then, once prompted, enter a value for the secret. The secret is output to the Terminal as you type it.
- The easiest way to send email from a Rust Cloudflare worker is using a REST API, assuming you have an account with SendGrid or another similar transactional email service. SendGrid and other services have APIs and typically you send a POST request to their endpoint from your worker. We have seen with SendGrid that the data in encoded as a JSON object. We use serde to help form the JSON data object from our Rust code. To make the REST call we used Reqwest. To access these from our Rust Cloudflare worker, we just needed to include them in Cargo.toml like other Rust crates we use in standalone Rust apps. An alternative is to use a Mail Transfer Agent, using TLS so the message is encrypted in transport. The advantage of this approach is that it is easier to switch to a different email service, especially if you have to do so at short notice.
Have you found the post useful? Would you prefer to see posts on another topic instead? Get in touch with ideas for new posts. Also if you like my writing style, get in touch if I can write some posts for your company site on a consultancy basis. Read on to find ways to get in touch, further below. If you want to support posts similar to this one and can spare a few dollars, euros or pounds, please consider supporting me through Buy me a Coffee.
Finally, feel free to share the post on your social media accounts for all your followers who will find it useful. As well as leaving a comment below, you can get in touch via @askRodney on Twitter and also askRodney on Telegram . Also, see further ways to get in touch with Rodney Lab. I post regularly on Astro as well as SvelteKit. Also subscribe to the newsletter to keep up-to-date with our latest projects.