My previous post on working towards a shell of a Rust web application covered global, static application settings and logging. There is still, probably, a change to come to allow for structured logging. However, this time lets start with the actual framework I’m using. First I download Iron, but it doesn’t feel right and I notice it hasn’t been worked on for two years. That’s an immediate clue to keep looking, so I move on to another I have heard mentioned: Rocket.
I’ve been listening to the archives of the mostly-discontinued podcast New Rustacean by Chris Krycho and, even though they are a couple of years old now (which is pretty old considering the pace of Rust), I still get an idea of where Rust started and how far it has come. Two episodes I just listened to – a 2016 episode about Diesel and a 2017 episode about Rocket – even helped me with this web application example I’m working on. It’s impressive these two Crates have continued getting updates and support after a couple of years. I’ll talk about Diesel in the next post, but for now let’s look at Rocket, plus some add-ons for templating, static web serving, web security, and interactive communication.
Rocket – Rust Framework
The Rocket crate received some high praise from Krycho in his “Crates You Should Know” episode and it seems the maintainers have continued with what impressed him. Rocket has a fantastic website and documentation guide making it a breeze to get started. The built-in route handling reminds me of perl Catalyst (how different could it be?). This feels very familiar. Here is my (simplified at this early point) implementation of getting Rocket started in my web application. The global static CONFIG I talked about last time continues to help here:
pub fn start_webservice() {
// start rocket webservice
let bind_address = &CONFIG.webservice.bind_address;
let bind_port = &CONFIG.webservice.bind_port;
let version = include_str!("version.txt");
rocket::ignite()
.attach(Template::fairing())
.attach(SpaceHelmet::default())
.mount("/", routes![routes::index])
.mount("/img", StaticFiles::from("src/view/static/img")}
.mount("/css", StaticFiles::from("src/view/static/css"))
.mount("/js", StaticFiles::from("src/view/static/js"))
.launch();
warn!( "Listening on {}:{} as version {}",
bind_address, bind_port, version );
}
Just as important as Rocket, in my view, are the capabilities added with the rocket_contrib crate. You can see some of them referenced in the chain of functions getting Rocket configured and running in my code above. So far, I already pull in the handlebars_templates, serve, helmet and JSON features.
rocket_contrib::handlebars_templates
I am pretty familiar with Template::Toolkit for use with Perl, but I’m only getting started with handlebars. Also, there is another rocket_contrib::templates option called tera templates. I mostly picked one of the two at random. I’m not yet to the point of working in HTML templates for this sample app, so this choice might change in the future. Who knows – maybe we need the option of a Template::Toolkit add-on as well!?
rocket_contrib::serve
Since Rocket builds-in the webserver funcionality (and I’m not sure I like this – I think I can front the web application with Nginx or some other service, so I need to look into that), I need it to serve local, static files (like CSS, Javascript, and images) as well. Rocket_contrib::serve handles this job for me with just some mount calls in the Rocket chain (see above). Again, I’m just getting set up, but this seems a good first step to get me going.
rocket_contrib::helmet
Security needs to extend past the coding language, of course, and rocket_contrib::helmet gives you a start at just a couple of HTTP concerns. The web is an absolutely crazy place – having read The Tangled Web by Michal Zalewski, I’m even more acutely aware of the convoluted and contentious history of web servers, web browsers, and the web languages we’ve ended up with, and I’m surprised things work at all! If helmet stops even one or two classes of those dangers, in it goes.
rocket_contrib::JSON
JSON is convenient to let the client browser (with Javascript) communicate back and forth with the server via (ahem) AJAX calls. I’ve included rocket_contrib::json just for this eventuality. Maybe there a more Rustic device or maybe this is still just “one way to do it”. I’ll learn more when I get to that point.
Ok, next up, we talk about the all-important ORM piece. I’m really impressed with Diesel so far, especially with the guide and documentation… but we’ll get to that with the next post.
The post My Next Step in Rust Web Application Dev appeared first on Learning Rust.
Top comments (0)