Rocket/site/news/2023-05-26-version-0.5.md

9.2 KiB

Rocket v0.5: Stable, Async, Sentinels, Figment, Shield, Streams, SSE, WebSockets, & More!

Posted by Sergio Benitez on May 26, 2023

Four years, almost a thousand commits, and over a thousand issues, discussions, and PRs later, I am relieved thrilled to announce the general availability of Rocket v0.5.

Rocket is a backend web framework for Rust with a focus on usability, security, extensibility, and speed. Rocket makes it simple to write secure web applications without sacrificing usability or performance.

We encourage all users to upgrade. For a guided upgrade from Rocket v0.4 to Rocket v0.5, please consult the newly available upgrading guide. Rocket v0.4 will continue to be supported and receive security updates until the next major release.

What's New?

Almost every aspect has been reevaluated with a focus on usability, security, and consistency across the library and broader ecosystem. The changes are numerous, so we focus on the most impactful changes here and encourage everyone to read the CHANGELOG for a complete list. For answers to frequently asked questions, see the new FAQ.

Support for Stable rustc

Rocket v0.5 compiles and builds on Rust stable with an entirely asynchronous core. This means that you can compile Rocket application with rustc from the stable release channel.

Using the stable release channel ensures that no breakages will occur when upgrading your Rust compiler or Rocket. That being said, Rocket continues to take advantage of features only present in the nightly channel.

📥 Async I/O

The new asynchronous core requires an async runtime to run. The new [launch] and [main] attributes simplify starting a runtime suitable for running Rocket applications. You should use [launch] whenever possible.

Additionally, the rocket::ignite() function has been renamed to [rocket::build()]; calls to the function or method should be replaced accordingly. Together, these two changes result in the following diff to what was previously the main function:

- fn main() {
-     rocket::ignite().mount("/hello", routes![hello]).launch();
- }
+ #[launch]
+ fn rocket() -> _ {
+     rocket::build().mount("/hello", routes![hello])
+ }

💂 Sentinels

Rocket v0.5 introduces sentinels. Entirely unique to Rocket, sentinels offer an automatic last line of defense against runtime errors by enabling any type that appears in a route to abort application launch if invalid conditions are detected. For example, the &State<T> guard in v0.5 is a Sentinel that aborts launch if the type T is not in managed state, thus preventing associated runtime errors.

You should consider implementing Sentinel for your types if you have guards (request, data, form, etc.) or responders that depend on Rocket state to function properly. For example, consider a MyResponder that expects:

  • An error catcher to be registered for the 400 status code.
  • A specific type T to be in managed state.

Making MyResponder a sentinel that guards against these conditions is as simple as:

use rocket::{Rocket, Ignite, Sentinel};
# struct MyResponder;
# struct T;

impl Sentinel for MyResponder {
    fn abort(r: &Rocket<Ignite>) -> bool {
        !r.catchers().any(|c| c.code == Some(400)) || r.state::<T>().is_none()
    }
}

🛡️ Shield

🌊 Streams and SSE

Rocket v0.5 introduces real-time, typed, async streams. The new async streams section of the guide contains further details, and we encourage all interested parties to see the new real-time, multi-room chat example.

As a taste of what's possible, the following stream route emits a "ping" Server-Sent Event every n seconds, defaulting to 1:

# use rocket::*;
use rocket::response::stream::{Event, EventStream};;
use rocket::tokio::time::{interval, Duration};

#[get("/ping?<n>")]
fn stream(n: Option<u64>) -> EventStream![] {
    EventStream! {
        let mut timer = interval(Duration::from_secs(n.unwrap_or(1)));
        loop {
            yield Event::data("ping");
            timer.tick().await;
        }
    }
}

🔌 WebSockets

Rocket v0.5 introduces support for HTTP connection upgrades via a new upgrade API. The API allows responders to take over an HTTP connection and perform raw I/O with the client. In other words, an HTTP connection can be upgraded to any protocol, including HTTP WebSockets!

The newly introduced rocket_ws library takes advantage of the new API to implement first-class support for WebSockets entirely outside of Rocket's core. The simplest use of the library, implementing an echo server and showcasing that the incoming message stream is async, looks like this:

# use rocket::get;
# use rocket_ws as ws;

#[get("/echo")]
fn echo_compose(ws: ws::WebSocket) -> ws::Stream!['static] {
    ws.stream(|io| io)
}

The simplified async streams generator syntax can also be used:

# use rocket::get;
# use rocket_ws as ws;

#[get("/echo")]
fn echo_stream(ws: ws::WebSocket) -> ws::Stream!['static] {
    ws::Stream! { ws =>
        for await message in ws {
            yield message?;
        }
    }
}

For complete usage details, see the rocket_ws documentation.

Thank You

  • Aaron Leopold
  • Abdullah Alyan
  • Aditya
  • Alex Macleod
  • Alex Sears
  • Alexander van Ratingen
  • ami-GS
  • Antoine Martin
  • arctic-alpaca
  • arlecchino
  • Arthur Woimbée
  • atouchet
  • Aurora
  • badoken
  • Beep LIN
  • Ben Sully
  • Benedikt Weber
  • BlackDex
  • Bonex
  • Brenden Matthews
  • Brendon Federko
  • Brett Buford
  • Cedric Hutchings
  • Cezar Halmagean
  • Charles-Axel Dein
  • Compro Prasad
  • Daniel Wiesenberg
  • David Venhoek
  • Dimitri Sabadie
  • Dinu Blanovschi
  • Dominik Boehi
  • Doni Rubiagatra
  • Edgar Onghena
  • Edwin Svensson
  • est31
  • Felix Suominen
  • Filip Gospodinov
  • Flying-Toast
  • Follpvosten
  • Francois Stephany
  • Gabriel Fontes
  • gcarq
  • George Cheng
  • Giles Cope
  • Gonçalo Ribeiro
  • hiyoko3m
  • Howard Su
  • hpodhaisky
  • Ian Jackson
  • IFcoltransG
  • Indosaram
  • inyourface34456
  • J. Cohen
  • Jacob Pratt
  • Jacob Sharf
  • Jacob Simpson
  • Jakub Dąbek
  • Jakub Wieczorek
  • James Tai
  • Jason Hinch
  • Jeb Rosen
  • Jeremy Kaplan
  • Joakim Soderlund
  • Johannes Liebermann
  • John-John Tedro
  • Jonah Brüchert
  • Jonas Møller
  • Jonathan Dickinson
  • Jonty
  • Joscha
  • Joshua Nitschke
  • JR Heard
  • Juhasz Sandor
  • Julian Büttner
  • Juraj Fiala
  • Kenneth Allen
  • Kevin Wang
  • Kian-Meng Ang
  • Konrad Borowski
  • Leonora Tindall
  • lewis
  • Lionel G
  • Lucille Blumire
  • Mai-Lapyst
  • Manuel
  • Marc Schreiber
  • Marc-Stefan Cassola
  • Marshall Bowers
  • Martin1887
  • Martinez
  • Matthew Pomes
  • Maxime Guerreiro
  • meltinglava
  • Michael Howell
  • Mikail Bagishov
  • mixio
  • multisn8
  • Necmettin Karakaya
  • Ning Sun
  • Nya
  • Paolo Barbolini
  • Paul Smith
  • Paul van Tilburg
  • Paul Weaver
  • pennae
  • Petr Portnov
  • philipp
  • Pieter Frenssen
  • PROgrm_JARvis
  • Razican
  • Redrield
  • Rémi Lauzier
  • Riley Patterson
  • Rodolphe Bréard
  • Roger Mo
  • RotesWasser
  • rotoclone
  • Rudi Floren
  • Samuele Esposito
  • Scott McMurray
  • Sergio Benitez
  • Silas Sewell
  • Soham Roy
  • Stuart Hinson
  • Thibaud Martinez
  • Thomas Eckert
  • ThouCheese
  • Tilen Pintarič
  • timando
  • timokoesters
  • toshokan
  • TotalKrill
  • Vasili
  • Vladimir Ignatev
  • Wesley Norris
  • xelivous
  • YetAnotherMinion
  • Yohannes Kifle
  • Yusuke Kominami

What's Next?