Stateful website with Rocket
I wanted to try replacing my Flask
webserver for some local home projects with Rust. I decided to use Rocket
, but I didn’t quite know how to keep some of the statefulness that I needed. Fortunately, in fewer than five minutes, I found the answer in Rocket’s docs: State
.
Here’s a simple webserver that hosts a page at /hello/<name>/<age>
(eg, /hello/dave/52
), keeps track of the most recent person to visit, and displays messages accordingly:
#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use]
extern crate rocket;
use rocket::State;
use std::sync::Mutex;
#[get("/hello/<name>/<age>")]
fn hello(last_person: State<Mutex<(String, u8)>>, name: String, age: u8) -> String {
// Acquire the lock mutably,
let guard = &mut last_person.lock().unwrap();
// get the name from the lock,
let prev_name = guard.0.clone();
// then update it. One deref gets the MutexGuard from its &mut; another gets the values from the Guard
**guard = (name, age);
// We've moved name & age into the guard, so we have to use that instead
if prev_name.is_empty() {
format!(
"Hello, {} year old named {}! You're the first person to show up",
guard.0, guard.1
)
} else {
format!(
"Hello, {} year old named {}! I just saw {}.",
guard.0, guard.1, prev_name
)
}
}
fn main() {
rocket::ignite()
// Start with empty state:
.manage(Mutex::new((String::new(), 0u8)))
.mount("/", routes![hello])
.launch();
}