Cover Photo by Hanbyul Jeong on Unsplash
It’s 1:00 AM (🎵 soft jazz music). You’re lying in bed trying to get some sleep. The city lights shine into your bedroom, softly illuminating the wall in front of you. You can hear the rain outside and the sound of people going about their late-night business. You can’t fall asleep. Something is bothering you, and you feel like you have to get it off your chest. You have to tell someone, but you don’t want to do it on social media. You want to spill your guts but remain completely anonymous. If only there was a place you could do this…
This is the setting we are going to use for the project of this post — Late Night Confessions : A 🦀 Rust-based website built using Rocket (web framework), Diesel (ORM), and Askama (template rendering engine).
The site functionality is pretty simple:
- Show the user a random confession.
- Allow the user to add a new confession.
Since we want to keep our confessions anonymous, we will not create a signup or login form.
Our site has three types of requests to handle:
- Static content requests — to get static files (i.e., index.html, styles.css)
- API request to get a confession.
- API request to post a confession.
All confessions will be saved in a Postgres database instance. We will use Diesel to manage the database activities.
Our finished project will look something like this:
The full source code can be found on Github.
We begin by creating a new crate for our project called late-night-rocket:
cargo new late-night-rocket
Next, let’s add Rocket and Failure as dependencies to our Cargo.toml:
🔭 Why do we need to specifically specify the_
0.5.0-devversion? Since we want our app to run on a stable Rust release,
0.5.0-devis (as of writing this post) the only version that supports stable Rust.
Rocket makes heavy use of macros. This means our first order of business is to import all of them to our crate. We do this by adding the
macro_use attribute to the top of our main.rs file, pointing to the Rocket crate:
Next, let’s add some
use statements to import modules we would need:
Finally, it’s time to create some routes!
1. We begin with the
root route responsible for rendering the content of index.html when the
/ path is called:
🔬 So what do we have here?
Line 1: Say hello to our first Rocket attribute —
route. Using this attribute, we define an HTTP method for our route (i.e
post), a path (either static or dynamic), and an optional data parameter (not needed here since we are defining a
Lines 3–5: We use the
NamedFilestruct to try and open the index.html file (we will create it next), and if we are successful, return the content of the file (the file extension determines the content type automatically). If we fail, we map the errors to a
NotFounderror type and return it. Notice the use of
awaiton line 4. We are asynchronously loading the file so that other operations won't have to wait for the file to load to continue processing.
static_files, as the name suggests, will handle requests for static files, such as images:
The route looks very similar to the
root route, with one noticeable difference; unlike the static
root route, this route is dynamic, meaning it matches anything after the
/ as the
path variable. We then use this
path variable and append it to the site folder (line 3) before trying to get the file (using
NamedFile, just like in the previous route).
3. Next, we mount the new routes to a
Rocket instance using the
🔬So what do we have here?
build a new
Rocket instance, then we mount the routes using the
mount method, which takes two parameters as input:
- A base path to use on all the associated routes (
/in our case)
- A list of routes via the
4. Finally, we need to launch our rocket for it to serve requests. There are two mechanisms to launch a
Rocket instance, but we will focus on the preferred approach for this tutorial's purposes: the
launch attribute. Add it above the
rocket function defined in the previous step:
5. At the root of our project, create a new folder named site and inside of it, create a folder named static.
6. Inside the static folder, create an index.html file with the following content:
- Create an empty styles.css file in the same folder. We will populate it later on.
Go ahead and
cargo run the project and then browse to localhost:8000. Congratulations, you have a working Rocket server!
With our server up and running, we are ready to take on the next task and pour some Diesel (pun intended) into our Rocket to gain database support!