# 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. [upgrading guide]: ../../guide/upgrading ## 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]. [broader ecosystem]: ../../guide/faq/#releases [CHANGELOG]: https://github.com/SergioBenitez/Rocket/blob/v0.5.0/CHANGELOG.md [FAQ]: ../../guide/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: ```diff - 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`] 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: ```rust use rocket::{Rocket, Ignite, Sentinel}; # struct MyResponder; # struct T; impl Sentinel for MyResponder { fn abort(r: &Rocket) -> bool { !r.catchers().any(|c| c.code == Some(400)) || r.state::().is_none() } } ``` [sentinels]: @api/rocket/trait.Sentinel.html [`Sentinel`]: @api/rocket/trait.Sentinel.html [`&State`]: @api/rocket/struct.State.html ### 🛡️ 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`: ```rust # use rocket::*; use rocket::response::stream::{Event, EventStream};; use rocket::tokio::time::{interval, Duration}; #[get("/ping?")] fn stream(n: Option) -> EventStream![] { EventStream! { let mut timer = interval(Duration::from_secs(n.unwrap_or(1))); loop { yield Event::data("ping"); timer.tick().await; } } } ``` [streams]: @api/rocket/response/stream/index.html [async streams]: @guide/responses/#async-streams [chat example]: @example/chat ### 🔌 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: ```rust # 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: ```rust # 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. [upgrade API]: @api/rocket/response/struct.Response.html#upgrading [`rocket_ws`]: @api/rocket_ws [GitHub issue tracker]: https://github.com/SergioBenitez/Rocket/issues [GitHub discussions]: https://github.com/SergioBenitez/Rocket/discussions [migration guide]: ../../guide/upgrading [CHANGELOG]: https://github.com/SergioBenitez/Rocket/blob/v0.5/CHANGELOG.md#version-050-rc2-may-9-2022 ## 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?