mirror of https://github.com/rwf2/Rocket.git
326 lines
9.2 KiB
Markdown
326 lines
9.2 KiB
Markdown
|
# Rocket v0.5: Stable, Async, Sentinels, Figment, Shield, Streams, SSE, WebSockets, & More!
|
||
|
|
||
|
<p class="metadata"><strong>
|
||
|
Posted by <a href="https://sergio.bz">Sergio Benitez</a> on May 26, 2023
|
||
|
</strong></p>
|
||
|
|
||
|
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<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:
|
||
|
|
||
|
```rust
|
||
|
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()
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
[sentinels]: @api/rocket/trait.Sentinel.html
|
||
|
[`Sentinel`]: @api/rocket/trait.Sentinel.html
|
||
|
[`&State<T>`]: @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?<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;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
[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-rc/CHANGELOG.md#version-050-rc2-may-9-2022
|
||
|
|
||
|
## Thank You
|
||
|
|
||
|
<ul class="columns">
|
||
|
<li>Aaron Leopold</li>
|
||
|
<li>Abdullah Alyan</li>
|
||
|
<li>Aditya</li>
|
||
|
<li>Alex Macleod</li>
|
||
|
<li>Alex Sears</li>
|
||
|
<li>Alexander van Ratingen</li>
|
||
|
<li>ami-GS</li>
|
||
|
<li>Antoine Martin</li>
|
||
|
<li>arctic-alpaca</li>
|
||
|
<li>arlecchino</li>
|
||
|
<li>Arthur Woimbée</li>
|
||
|
<li>atouchet</li>
|
||
|
<li>Aurora</li>
|
||
|
<li>badoken</li>
|
||
|
<li>Beep LIN</li>
|
||
|
<li>Ben Sully</li>
|
||
|
<li>Benedikt Weber</li>
|
||
|
<li>BlackDex</li>
|
||
|
<li>Bonex</li>
|
||
|
<li>Brenden Matthews</li>
|
||
|
<li>Brendon Federko</li>
|
||
|
<li>Brett Buford</li>
|
||
|
<li>Cedric Hutchings</li>
|
||
|
<li>Cezar Halmagean</li>
|
||
|
<li>Charles-Axel Dein</li>
|
||
|
<li>Compro Prasad</li>
|
||
|
<li>Daniel Wiesenberg</li>
|
||
|
<li>David Venhoek</li>
|
||
|
<li>Dimitri Sabadie</li>
|
||
|
<li>Dinu Blanovschi</li>
|
||
|
<li>Dominik Boehi</li>
|
||
|
<li>Doni Rubiagatra</li>
|
||
|
<li>Edgar Onghena</li>
|
||
|
<li>Edwin Svensson</li>
|
||
|
<li>est31</li>
|
||
|
<li>Felix Suominen</li>
|
||
|
<li>Filip Gospodinov</li>
|
||
|
<li>Flying-Toast</li>
|
||
|
<li>Follpvosten</li>
|
||
|
<li>Francois Stephany</li>
|
||
|
<li>Gabriel Fontes</li>
|
||
|
<li>gcarq</li>
|
||
|
<li>George Cheng</li>
|
||
|
<li>Giles Cope</li>
|
||
|
<li>Gonçalo Ribeiro</li>
|
||
|
<li>hiyoko3m</li>
|
||
|
<li>Howard Su</li>
|
||
|
<li>hpodhaisky</li>
|
||
|
<li>Ian Jackson</li>
|
||
|
<li>IFcoltransG</li>
|
||
|
<li>Indosaram</li>
|
||
|
<li>inyourface34456</li>
|
||
|
<li>J. Cohen</li>
|
||
|
<li>Jacob Pratt</li>
|
||
|
<li>Jacob Sharf</li>
|
||
|
<li>Jacob Simpson</li>
|
||
|
<li>Jakub Dąbek</li>
|
||
|
<li>Jakub Wieczorek</li>
|
||
|
<li>James Tai</li>
|
||
|
<li>Jason Hinch</li>
|
||
|
<li>Jeb Rosen</li>
|
||
|
<li>Jeremy Kaplan</li>
|
||
|
<li>Joakim Soderlund</li>
|
||
|
<li>Johannes Liebermann</li>
|
||
|
<li>John-John Tedro</li>
|
||
|
<li>Jonah Brüchert</li>
|
||
|
<li>Jonas Møller</li>
|
||
|
<li>Jonathan Dickinson</li>
|
||
|
<li>Jonty</li>
|
||
|
<li>Joscha</li>
|
||
|
<li>Joshua Nitschke</li>
|
||
|
<li>JR Heard</li>
|
||
|
<li>Juhasz Sandor</li>
|
||
|
<li>Julian Büttner</li>
|
||
|
<li>Juraj Fiala</li>
|
||
|
<li>Kenneth Allen</li>
|
||
|
<li>Kevin Wang</li>
|
||
|
<li>Kian-Meng Ang</li>
|
||
|
<li>Konrad Borowski</li>
|
||
|
<li>Leonora Tindall</li>
|
||
|
<li>lewis</li>
|
||
|
<li>Lionel G</li>
|
||
|
<li>Lucille Blumire</li>
|
||
|
<li>Mai-Lapyst</li>
|
||
|
<li>Manuel</li>
|
||
|
<li>Marc Schreiber</li>
|
||
|
<li>Marc-Stefan Cassola</li>
|
||
|
<li>Marshall Bowers</li>
|
||
|
<li>Martin1887</li>
|
||
|
<li>Martinez</li>
|
||
|
<li>Matthew Pomes</li>
|
||
|
<li>Maxime Guerreiro</li>
|
||
|
<li>meltinglava</li>
|
||
|
<li>Michael Howell</li>
|
||
|
<li>Mikail Bagishov</li>
|
||
|
<li>mixio</li>
|
||
|
<li>multisn8</li>
|
||
|
<li>Necmettin Karakaya</li>
|
||
|
<li>Ning Sun</li>
|
||
|
<li>Nya</li>
|
||
|
<li>Paolo Barbolini</li>
|
||
|
<li>Paul Smith</li>
|
||
|
<li>Paul van Tilburg</li>
|
||
|
<li>Paul Weaver</li>
|
||
|
<li>pennae</li>
|
||
|
<li>Petr Portnov</li>
|
||
|
<li>philipp</li>
|
||
|
<li>Pieter Frenssen</li>
|
||
|
<li>PROgrm_JARvis</li>
|
||
|
<li>Razican</li>
|
||
|
<li>Redrield</li>
|
||
|
<li>Rémi Lauzier</li>
|
||
|
<li>Riley Patterson</li>
|
||
|
<li>Rodolphe Bréard</li>
|
||
|
<li>Roger Mo</li>
|
||
|
<li>RotesWasser</li>
|
||
|
<li>rotoclone</li>
|
||
|
<li>Rudi Floren</li>
|
||
|
<li>Samuele Esposito</li>
|
||
|
<li>Scott McMurray</li>
|
||
|
<li>Sergio Benitez</li>
|
||
|
<li>Silas Sewell</li>
|
||
|
<li>Soham Roy</li>
|
||
|
<li>Stuart Hinson</li>
|
||
|
<li>Thibaud Martinez</li>
|
||
|
<li>Thomas Eckert</li>
|
||
|
<li>ThouCheese</li>
|
||
|
<li>Tilen Pintarič</li>
|
||
|
<li>timando</li>
|
||
|
<li>timokoesters</li>
|
||
|
<li>toshokan</li>
|
||
|
<li>TotalKrill</li>
|
||
|
<li>Vasili</li>
|
||
|
<li>Vladimir Ignatev</li>
|
||
|
<li>Wesley Norris</li>
|
||
|
<li>xelivous</li>
|
||
|
<li>YetAnotherMinion</li>
|
||
|
<li>Yohannes Kifle</li>
|
||
|
<li>Yusuke Kominami</li>
|
||
|
</ul>
|
||
|
|
||
|
## What's Next?
|