mirror of https://github.com/rwf2/Rocket.git
Polish news for v0.5. Add RWF2 announcement.
This commit is contained in:
parent
f7a6c8610e
commit
b70c237461
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
[release]
|
[release]
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
date = "Nov XX, 2023"
|
date = "Nov 17, 2023"
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Top features: displayed in the header under the introductory text.
|
# Top features: displayed in the header under the introductory text.
|
||||||
|
|
|
@ -1,325 +0,0 @@
|
||||||
# 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/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?
|
|
|
@ -0,0 +1,253 @@
|
||||||
|
# Building a Better Foundation for Rocket's Future
|
||||||
|
|
||||||
|
<p class="metadata"><strong>
|
||||||
|
Posted by <a href="https://sergio.bz">Sergio Benitez</a> on Nov 17, 2023
|
||||||
|
</strong></p>
|
||||||
|
|
||||||
|
Along with the [release of Rocket v0.5], today I'm sharing plans to launch the
|
||||||
|
Rocket Web Framework Foundation, or [_RWF2_]. The RWF2 is a nonprofit
|
||||||
|
organization designed to support Rocket and the surrounding ecosystem,
|
||||||
|
financially and organizationally.
|
||||||
|
|
||||||
|
I'm also directly addressing the community's concerns regarding the pace of
|
||||||
|
Rocket's development, leadership, and release cadence. My hope is to assuage any
|
||||||
|
and all concerns about Rocket's future. I hope reading this leaves you feeling
|
||||||
|
confident that Rocket is here to stay, and that the RWF2 is the right step
|
||||||
|
towards increased community contributions and involvement.
|
||||||
|
|
||||||
|
! note: This is a co-announcement [along with release of Rocket v0.5].
|
||||||
|
|
||||||
|
[along with release of Rocket v0.5]: ../2023-11-17-version-0.5/
|
||||||
|
[release of Rocket v0.5]: ../2023-11-17-version-0.5/
|
||||||
|
[_RWF2_]: https://rwf2.org
|
||||||
|
[RWF2]: https://rwf2.org
|
||||||
|
|
||||||
|
## Background
|
||||||
|
|
||||||
|
I released Rocket in 2016 to fanfare. It was lauded as _the_ web framework for
|
||||||
|
Rust. But in the last few years, I'd be remiss to claim the same. New frameworks
|
||||||
|
have emerged, Rocket's recent development has been nothing short of erratic, and
|
||||||
|
four years went by without a major release.
|
||||||
|
|
||||||
|
The community rightfully voiced its disappointment and concern. Posts inquired
|
||||||
|
about the project's status: was it dead? I received copious email ranging from
|
||||||
|
concern over my well-being, to anger, to requests to transfer the project
|
||||||
|
entirely. The community ~~wasn't~~ isn't happy with Rocket.
|
||||||
|
|
||||||
|
And I get it. I failed to adequately lead the project. I failed to communicate
|
||||||
|
when it mattered most. I couldn't control the life events that pulled me away
|
||||||
|
from Rocket and most of my responsibilities, but I could have done more to
|
||||||
|
communicate what was going on. And I certainly could have done _something_ to
|
||||||
|
make it easy, make it _possible_ for others to push the project forward in my
|
||||||
|
absense.
|
||||||
|
|
||||||
|
But I did none of that. I couldn't make it happen. And I'm truly, sincerely
|
||||||
|
sorry.
|
||||||
|
|
||||||
|
## A Better Foundation for Rocket's Future
|
||||||
|
|
||||||
|
I'd like to make it impossible to repeat these mistakes. That's why today I'm
|
||||||
|
announcing plans for a new independent nonprofit foundation designed to support
|
||||||
|
and bolster Rocket's development, increase transparency, and diversify project
|
||||||
|
leadership: [RWF2].
|
||||||
|
|
||||||
|
> The **R**ocket **W**eb **F**ramework **F**oundation, _RWF2_, is a
|
||||||
|
> <abbr title="RWF2 is granted 501(c)(3) status via its fiscal host, the OCF.">
|
||||||
|
> 501(c)(3) nonprofit</abbr> and <a href="https://opencollective.com/rwf2">
|
||||||
|
> collective</a> that supports the development and community of free and open
|
||||||
|
> source software, like <a href="https://rocket.rs">Rocket</a>, as well as
|
||||||
|
> education for a more secure web.
|
||||||
|
|
||||||
|
Moving forward, the RWF2 will be responsible for governing Rocket and dictating
|
||||||
|
its trajectory. The goal is to distribute control of the project and prohibit
|
||||||
|
one person from being able to stall its development. The RWF2 will also act as a
|
||||||
|
vehicle for tax-deductible contributions, funds management, and development
|
||||||
|
grant distribution, all with the aim of increasing high-quality contributions
|
||||||
|
and educational material.
|
||||||
|
|
||||||
|
In summary, the RWF2 exists to enable:
|
||||||
|
|
||||||
|
* **Diversified Leadership**
|
||||||
|
|
||||||
|
Key responsibilities, such as releases, security, infrastructure, and
|
||||||
|
community engagement will be distributed to community members under the
|
||||||
|
umbrella of the foundation.
|
||||||
|
|
||||||
|
* **Tax-Deductible Contributions**
|
||||||
|
|
||||||
|
Because the RWF2 is a 501(c)(3) organization, contributions are
|
||||||
|
tax-deductible. We particularly hope this encourages corporate sponsorship,
|
||||||
|
especially from those who depend on Rocket. As a nonprofit, the RWF2 must
|
||||||
|
transparently manage and disburse all funds.
|
||||||
|
|
||||||
|
* **Development Grants**
|
||||||
|
|
||||||
|
A key use for contributions is the foundation's sponsorship and
|
||||||
|
administration of µGrants: small (≤ $1k) grants for concrete work on
|
||||||
|
Rocket or related projects. Compensation is staged upon completion of
|
||||||
|
predefined milestones and quality requirements.
|
||||||
|
|
||||||
|
* **Increased Transparency**
|
||||||
|
|
||||||
|
Milestones, release schedules, and periodic updates form part of the
|
||||||
|
foundation's responsibilities. The aim is to keep the community informed on
|
||||||
|
Rocket's development and plans, making it easier to get and remain involved.
|
||||||
|
|
||||||
|
* **Educational Resource Expansion**
|
||||||
|
|
||||||
|
The RWF2 aims to enhance the accessibility of educational resources,
|
||||||
|
training, and mentorship for web application security, especially for
|
||||||
|
traditionally marginalized groups. Our focus lies in delivering
|
||||||
|
high-quality, practical materials for building secure web applications.
|
||||||
|
|
||||||
|
## What's Happening Now
|
||||||
|
|
||||||
|
There's a lot to do to realize these goals, but the process starts today. Here's
|
||||||
|
what's being done now:
|
||||||
|
|
||||||
|
0. **Open Sponsorship**
|
||||||
|
|
||||||
|
Starting now, you can sponsor the RWF2 through [GitHub Sponsors] or
|
||||||
|
[Open Collective]. Tiers are still a work in progress, but for now, consider
|
||||||
|
all tiers on Open Collective, and Bronze+ tiers on GitHub, as intended for
|
||||||
|
corporate sponsors. Note that only contributions made directly via Open
|
||||||
|
Collective are guaranteed to be tax-deductible.
|
||||||
|
|
||||||
|
A special shout out to `@martynp`, `@nathanielford`, and `@wezm` for
|
||||||
|
jumping the gun in the best of ways and sponsoring the RWF2 via GitHub
|
||||||
|
ahead of schedule. Thank you!
|
||||||
|
|
||||||
|
0. **Team Assembly**
|
||||||
|
|
||||||
|
Initially, RWF2 governance will be exceedingly simple and consist of a
|
||||||
|
president <small>(hi!)</small> and a handful of team leads. Individuals can
|
||||||
|
fill multiple positions, though the intent is for every position to be held
|
||||||
|
by a different individual. Positions are by appointment, either by the
|
||||||
|
presiding team lead, by the president in their absence, and by other team
|
||||||
|
leads in the president's absence.
|
||||||
|
|
||||||
|
The initial teams and their responsibilities are listed below. If you're
|
||||||
|
interested in leading any of the teams (or another team you think should
|
||||||
|
exist), please reach out via the [Matrix channel] or directly via
|
||||||
|
[foundation@rwf2.org](mailto:foundation@rwf2.org).
|
||||||
|
|
||||||
|
- *Maintenance*
|
||||||
|
|
||||||
|
Reviews issues, pull requests, and discussions, and acts on them as
|
||||||
|
necessary. This largely means triaging issues, closing resolved or
|
||||||
|
duplicate issues and discussions, closing or merging stale or approved
|
||||||
|
pull requests, respectively, and pinging the appropriate individuals to
|
||||||
|
prevent issues or PRs from becoming stale.
|
||||||
|
|
||||||
|
- *Release*
|
||||||
|
|
||||||
|
Publishes code and documentation releases. This includes partitioning
|
||||||
|
commits according to scope and impact on breakage, writing and updating
|
||||||
|
CHANGELOGs, and testing and publishing new releases and their
|
||||||
|
documentation.
|
||||||
|
|
||||||
|
- *Knowledge*
|
||||||
|
|
||||||
|
Creates, maintains and improves materials that help others learn about
|
||||||
|
Rocket or web security. This includes documentation like API docs and the
|
||||||
|
Rocket guide, code such as examples and tutorials, and materials for live
|
||||||
|
or in-person education.
|
||||||
|
|
||||||
|
- *Community*
|
||||||
|
|
||||||
|
Keeps the community adjourned on happenings. This involves writing
|
||||||
|
periodic project updates as well as digesting and communicating
|
||||||
|
development milestones and schedules to a broad audience.
|
||||||
|
|
||||||
|
- *Infrastructure*
|
||||||
|
|
||||||
|
Maintains infrastructure including: building, testing, and release
|
||||||
|
scripts, static site generation, CI and other automated processes, and
|
||||||
|
domain registrar and cloud computing services.
|
||||||
|
|
||||||
|
0. **Transfer of Assets**
|
||||||
|
|
||||||
|
The majority of Rocket's assets, including its domain, website, source
|
||||||
|
code, and associated infrastructure, are managed under personal accounts.
|
||||||
|
All assets are being transferred to foundation-owned accounts, and access
|
||||||
|
will be given to the appropriate teams. The [migration project on GitHub]
|
||||||
|
is tracking the progress of asset migration.
|
||||||
|
|
||||||
|
0. **Process Documentation**
|
||||||
|
|
||||||
|
Some of Rocket's core processes, including releases and site building, are
|
||||||
|
generally inaccessible to others. These will be documented, and access will
|
||||||
|
be granted to the appropriate teams.
|
||||||
|
|
||||||
|
0. **Open Planning & Development**
|
||||||
|
|
||||||
|
While Rocket's development has generally been done in the open through
|
||||||
|
GitHub issues, PRs, and projects, little has been done to publicize those
|
||||||
|
efforts. Furthermore, _planning_ has largely been a closed process. Moving
|
||||||
|
forward, planning will be done in the open, and the community team will be
|
||||||
|
engaged to publicize development efforts and progress.
|
||||||
|
|
||||||
|
[GitHub Sponsors]: https://github.com/sponsors/rwf2
|
||||||
|
[Open Collective]: https://opencollective.com/rwf2
|
||||||
|
[Matrix channel]: https://chat.mozilla.org/#/room/#rocket:mozilla.org
|
||||||
|
[migration project on GitHub]: https://github.com/orgs/rwf2/projects/1
|
||||||
|
|
||||||
|
## What's Coming Soon
|
||||||
|
|
||||||
|
* **µGrants**
|
||||||
|
|
||||||
|
The µGrant specification is a work-in-progress. We simulatenously want to
|
||||||
|
encourage and financially incentivize high-quality contributions while not
|
||||||
|
disincentivizing existing contributors. This is a delicate balance, and we
|
||||||
|
want to take the time to get it right. To get involved, see the current
|
||||||
|
[draft proposal](https://github.com/rwf2/rwf2.org/blob/master/docs/micro-grants.md) and
|
||||||
|
share your thoughts in the [GitHub discussion](https://github.com/orgs/rwf2/discussions/8).
|
||||||
|
As soon as we have a specification that feels fair, the first µGrants will
|
||||||
|
be offered.
|
||||||
|
|
||||||
|
* **Foundation Website**
|
||||||
|
|
||||||
|
The [RWF2 website](https://rwf2.org) as it stands is a placeholder for a
|
||||||
|
more fully featured website. Besides articulating the foundation's mission
|
||||||
|
and goals, the RWF2's website will also serve as a source of truth for the
|
||||||
|
status of and means to engaging with ongoing projects, grants, and finances.
|
||||||
|
|
||||||
|
* **Membership**
|
||||||
|
|
||||||
|
While certainly premature at this point in time, a consideration for the
|
||||||
|
future comes in the form of foundation _membership_ whereby governance is
|
||||||
|
expanded to include foundation _members_. The [governance proposal
|
||||||
|
document](https://github.com/rwf2/rwf2.org/blob/master/docs/governance.md)
|
||||||
|
has one take on how this might work. Until such a proposal is accepted,
|
||||||
|
governance will follow the president + teams model articulated above.
|
||||||
|
|
||||||
|
## How to Get Involved
|
||||||
|
|
||||||
|
The RWF2 represents a conscious effort to transfer control of Rocket from an
|
||||||
|
individual (me) to the community (you). Without your involvement, the RWF2
|
||||||
|
ceases to exist. If you're excited about Rocket or the foundation, or simply
|
||||||
|
want to see Rocket continue to exist and flourish, please get involved.
|
||||||
|
|
||||||
|
* **Join the Discussion**
|
||||||
|
|
||||||
|
Communicate with us via the [Matrix channel], via [GitHub
|
||||||
|
discussions](https://github.com/orgs/rwf2/discussions), or via email at
|
||||||
|
[foundation@rwf2.org](mailto:foundation@rwf2.org). The foundation bring-up
|
||||||
|
itself is designed to be collaborative, and any input you have is
|
||||||
|
invaluable.
|
||||||
|
|
||||||
|
* **Make a Contribution**
|
||||||
|
|
||||||
|
Any easy way to get involved is to financially contribute. You can sponsor
|
||||||
|
the RWF2 through [GitHub Sponsors] or [Open Collective]. If your company
|
||||||
|
uses Rocket, encourage it to sponsor the project through the foundation.
|
||||||
|
|
||||||
|
* **Become a Team Lead**
|
||||||
|
|
||||||
|
If you're interested in leading or learning more about any one of the
|
||||||
|
*Maintenance*, *Release*, *Knowledge*, *Community*, or *Infrastructure*
|
||||||
|
teams, or think another team should exist, please get in touch via the
|
||||||
|
[Matrix channel] or via email at [foundation@rwf2.org](mailto:foundation@rwf2.org).
|
||||||
|
|
||||||
|
I'm excited for this next step in Rocket's history, and I hope you'll join me in
|
||||||
|
making it a success.
|
|
@ -0,0 +1,622 @@
|
||||||
|
# Rocket v0.5: Stable, Async, Sentinels, Streams, SSE, Forms, WebSockets, & So Much More
|
||||||
|
|
||||||
|
<p class="metadata"><strong>
|
||||||
|
Posted by <a href="https://sergio.bz">Sergio Benitez</a> on Nov 17, 2023
|
||||||
|
</strong></p>
|
||||||
|
|
||||||
|
Four years, four release candidates, 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 an async 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 productivity or performance.
|
||||||
|
|
||||||
|
We encourage all users to upgrade. For a guided migration 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 time Rocket
|
||||||
|
v0.6 is released.
|
||||||
|
|
||||||
|
! note: This is a co-announcement [along with the prelaunch] of [RWF2].
|
||||||
|
|
||||||
|
We're addressing the community's concerns regarding the pace of Rocket's
|
||||||
|
development, leadership, and release cadence in a separate announcement.
|
||||||
|
Please see the accompanying [RWF2 prelaunch announcement](../2023-11-17-rwf2-prelaunch/)
|
||||||
|
to learn more and see how you can get involved.
|
||||||
|
|
||||||
|
[RWF2]: https://rwf2.org
|
||||||
|
[along with the prelaunch]: ../2023-11-17-rwf2-prelaunch/
|
||||||
|
[upgrading guide]: ../../guide/upgrading
|
||||||
|
|
||||||
|
## What's New?
|
||||||
|
|
||||||
|
Almost every bit has been reevaluated with a focus on usability and developer
|
||||||
|
productivity, security, and consistency across the library and [broader
|
||||||
|
ecosystem]. The changes are numerous, so we focus on the most noteworthy changes
|
||||||
|
here and encourage everyone to read the [CHANGELOG] for a complete list. For
|
||||||
|
answers to frequently asked questions, see the new [FAQ].
|
||||||
|
|
||||||
|
[CHANGELOG]: https://github.com/SergioBenitez/Rocket/blob/v0.5.0/CHANGELOG.md
|
||||||
|
[broader ecosystem]: ../../guide/faq/#releases
|
||||||
|
[FAQ]: ../../guide/faq
|
||||||
|
|
||||||
|
### ⚓ Support for Stable `rustc` <badge>since `rc.1`</badge>
|
||||||
|
|
||||||
|
Rocket v0.5 compiles and builds on Rust stable. You can now compile and build
|
||||||
|
Rocket applications with `rustc` from the stable release channel and remove all
|
||||||
|
`#![feature(..)]` crate attributes. The complete canonical example with a single
|
||||||
|
`hello` route becomes:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[macro_use] extern crate rocket;
|
||||||
|
|
||||||
|
#[get("/<name>/<age>")]
|
||||||
|
fn hello(name: &str, age: u8) -> String {
|
||||||
|
format!("Hello, {} year old named {}!", age, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[launch]
|
||||||
|
fn rocket() -> _ {
|
||||||
|
rocket::build().mount("/hello", routes![hello])
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>See a <code>diff</code> of the changes from v0.4.</summary>
|
||||||
|
|
||||||
|
```diff
|
||||||
|
- #![feature(proc_macro_hygiene, decl_macro)]
|
||||||
|
-
|
||||||
|
#[macro_use] extern crate rocket;
|
||||||
|
|
||||||
|
#[get("/<name>/<age>")]
|
||||||
|
- fn hello(name: String, age: u8) -> String {
|
||||||
|
+ fn hello(name: &str, age: u8) -> String {
|
||||||
|
format!("Hello, {} year old named {}!", age, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
- fn main() {
|
||||||
|
- rocket::ignite().mount("/hello", routes![hello]).launch();
|
||||||
|
- }
|
||||||
|
+ #[launch]
|
||||||
|
+ fn rocket() -> _ {
|
||||||
|
+ rocket::build().mount("/hello", routes![hello])
|
||||||
|
+ }
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
Note the new [`launch`] attribute, which simplifies starting an `async` runtime
|
||||||
|
for Rocket applications. See the [migration guide] for more on transitioning to
|
||||||
|
a stable toolchain.
|
||||||
|
|
||||||
|
[`launch`]: @api/rocket/attr.launch.html
|
||||||
|
|
||||||
|
### 📥 Async I/O <badge>since `rc.1`</badge>
|
||||||
|
|
||||||
|
Rocket's core request handling was rebuilt in v0.5 to take advantage of the
|
||||||
|
latest `async` networking facilities in Rust. Backed by `tokio`, Rocket
|
||||||
|
automatically multiplexes request handling across `async` tasks on all of the
|
||||||
|
available cores on the machine. As a result, route handlers can now be declared
|
||||||
|
`async` and make use of `await` syntax:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use rocket::tokio;
|
||||||
|
use rocket::data::{Data, ToByteUnit};
|
||||||
|
|
||||||
|
#[post("/debug", data = "<data>")]
|
||||||
|
async fn debug(data: Data<'_>) -> std::io::Result<()> {
|
||||||
|
// Stream at most 512KiB all of the body data to stdout.
|
||||||
|
data.open(512.kibibytes())
|
||||||
|
.stream_to(tokio::io::stdout())
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
See the [Blocking I/O](@guide/upgrading#blocking-io) section of the upgrading
|
||||||
|
guide for complete details on the `async` I/O transition.
|
||||||
|
|
||||||
|
### 💂 Sentinels <badge>since `rc.1`</badge>
|
||||||
|
|
||||||
|
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 under invalid conditions.
|
||||||
|
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.
|
||||||
|
|
||||||
|
[`Sentinel`]s can be implemented outside of Rocket, too, and you should seek to
|
||||||
|
do so whenever possible. For instance, the [`Template`] type from
|
||||||
|
[`rocket_dyn_templates`] is a sentinel that ensures templates are properly
|
||||||
|
registered. As another example, consider a `MyResponder` that expects:
|
||||||
|
|
||||||
|
* A specific type `T` to be in managed state.
|
||||||
|
* An catcher to be registered for the `400` status code.
|
||||||
|
|
||||||
|
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.state::<T>().is_none() || !r.catchers().any(|c| c.code == Some(400))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
[sentinels]: @api/rocket/trait.Sentinel.html
|
||||||
|
[`Sentinel`]: @api/rocket/trait.Sentinel.html
|
||||||
|
[`&State<T>`]: @api/rocket/struct.State.html
|
||||||
|
[`Template`]: @api/rocket_dyn_templates/struct.Template.html
|
||||||
|
[`rocket_dyn_templates`]: @api/rocket_dyn_templates/index.html
|
||||||
|
|
||||||
|
### ☄️ Streams and SSE <badge>since `rc.1`</badge>
|
||||||
|
|
||||||
|
Powered by the new asynchronous core, 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 `"pong"`
|
||||||
|
Server-Sent Event every `n` seconds, defaulting to `1`:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
# use rocket::*;
|
||||||
|
use rocket::tokio::time::{interval, Duration};
|
||||||
|
use rocket::response::stream::{Event, EventStream};;
|
||||||
|
|
||||||
|
#[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("pong");
|
||||||
|
timer.tick().await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
[streams]: @api/rocket/response/stream/index.html
|
||||||
|
[async streams]: @guide/responses/#async-streams
|
||||||
|
[chat example]: @example/chat
|
||||||
|
|
||||||
|
### 🔌 WebSockets <badge>since `rc.4`</badge>
|
||||||
|
|
||||||
|
Rocket v0.5 introduces support for HTTP connection upgrades via a new [upgrade
|
||||||
|
API]. The API allows responders to assume control of raw I/O with the client in
|
||||||
|
an existing HTTP connection, thus allowing HTTP connections to be _upgraded_ to
|
||||||
|
any protocol, including 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.
|
||||||
|
Working with `rocket_ws` to implement an echo server looks like this:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
# use rocket::get;
|
||||||
|
use rocket_ws::{WebSocket, Stream};
|
||||||
|
|
||||||
|
#[get("/echo")]
|
||||||
|
fn echo_compose(ws: WebSocket) -> Stream!['static] {
|
||||||
|
ws.stream(|io| io)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Just like the newly introduced `async` streams, `rocket_ws` also supports using
|
||||||
|
generator syntax for WebSocket messages:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
# use rocket::get;
|
||||||
|
use rocket_ws::{WebSocket, Stream};
|
||||||
|
|
||||||
|
#[get("/echo")]
|
||||||
|
fn echo_stream(ws: WebSocket) -> Stream!['static] {
|
||||||
|
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
|
||||||
|
|
||||||
|
### 📝 Comprehensive Forms <badge>since `rc.1`</badge>
|
||||||
|
|
||||||
|
Rocket v0.5 entirely revamps [forms] with support for [multipart uploads],
|
||||||
|
[arbitrary collections] with [arbitrary nesting], [ad-hoc validation], and an
|
||||||
|
improved [`FromForm` derive], obviating the need for nearly all custom
|
||||||
|
implementations of `FromForm` or `FromFormField`. Rocket's new wire protocol for
|
||||||
|
forms allows applications to express _any structure_ with _any level of nesting
|
||||||
|
and collection_ without any custom code, eclipsing what's offered by other web
|
||||||
|
frameworks.
|
||||||
|
|
||||||
|
As an illustrative example, consider the following structures:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use rocket::form::FromForm;
|
||||||
|
|
||||||
|
#[derive(FromForm)]
|
||||||
|
struct MyForm<'r> {
|
||||||
|
owner: Person<'r>,
|
||||||
|
pet: Pet<'r>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(FromForm)]
|
||||||
|
struct Person<'r> {
|
||||||
|
name: &'r str
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(FromForm)]
|
||||||
|
struct Pet<'r> {
|
||||||
|
name: &'r str,
|
||||||
|
#[field(validate = eq(true))]
|
||||||
|
good_pet: bool,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
To parse request data into a `MyForm`, a form with fields of `owner.name`,
|
||||||
|
`pet.name`, and `pet.good_pet` must be submitted. The ad-hoc validation on
|
||||||
|
`good_pet` validates that `good_pet` parses as `true`. Such a form, URL-encoded,
|
||||||
|
may look like:
|
||||||
|
|
||||||
|
```rust,ignore
|
||||||
|
"owner.name=Bob&pet.name=Sally&pet.good_pet=yes"
|
||||||
|
```
|
||||||
|
|
||||||
|
Rocket's derived `FromForm` implementation for `MyForm` will automatically parse
|
||||||
|
such a submission into the correct value:
|
||||||
|
|
||||||
|
```rust,ignore
|
||||||
|
MyForm {
|
||||||
|
owner: Person {
|
||||||
|
name: "Bob".into()
|
||||||
|
},
|
||||||
|
pet: Pet {
|
||||||
|
name: "Sally".into(),
|
||||||
|
good_pet: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# };
|
||||||
|
```
|
||||||
|
|
||||||
|
The rewritten [forms guide] provides complete details on revamped forms support.
|
||||||
|
|
||||||
|
[forms guide]: @guide/requests/#forms
|
||||||
|
[ad-hoc validation]: @guide/requests#ad-hoc-validation
|
||||||
|
[arbitrary nesting]: @guide/requests#nesting
|
||||||
|
[multipart uploads]: @guide/requests#multipart
|
||||||
|
[forms]: @guide/requests#forms
|
||||||
|
[`FromFormField`]: @api/rocket/form/trait.FromFormField.html
|
||||||
|
[arbitrary collections]: @guide/requests#collections
|
||||||
|
[`FromForm` derive]: @api/rocket/derive.FromForm.html
|
||||||
|
|
||||||
|
### 🚀 And so much more!
|
||||||
|
|
||||||
|
Rocket v0.5 introduces over **40** new features and major improvements! We
|
||||||
|
encourage everyone to review the [CHANGELOG] to learn about them all. Here are a
|
||||||
|
few more we don't want you to miss:
|
||||||
|
|
||||||
|
* An automatically enabled [`Shield`]: security and privacy headers for all responses.
|
||||||
|
* [Graceful shutdown] with configurable grace periods, [notification], and [shutdown fairings].
|
||||||
|
* An entirely new, flexible and robust [configuration system] based on [Figment].
|
||||||
|
* Type-system enforced [incoming data limits] to mitigate memory-based DoS attacks.
|
||||||
|
* Support for [mutual TLS] and client [`Certificate`]s.
|
||||||
|
* Asynchronous database pooling support via [`rocket_db_pools`].
|
||||||
|
* Compile-time URI literals via a fully revamped [`uri!`] macro.
|
||||||
|
|
||||||
|
[`Shield`]: @api/rocket/shield/struct.Shield.html
|
||||||
|
[graceful shutdown]: @api/rocket/config/struct.Shutdown.html#summary
|
||||||
|
[notification]: @api/rocket/struct.Shutdown.html
|
||||||
|
[shutdown fairings]: @api/rocket/fairing/trait.Fairing.html#shutdown
|
||||||
|
[configuration system]: @guide/configuration/#configuration
|
||||||
|
[Figment]: https://docs.rs/figment/
|
||||||
|
[incoming data limits]: @guide/requests/#streaming
|
||||||
|
[mutual TLS]: @guide/configuration/#mutual-tls
|
||||||
|
[`uri!`]: @api/rocket/macro.uri.html
|
||||||
|
[`rocket_db_pools`]: @api/rocket_db_pools/index.html
|
||||||
|
[`Certificate`]: @api/rocket/mtls/struct.Certificate.html
|
||||||
|
[migration guide]: ../../guide/upgrading
|
||||||
|
|
||||||
|
## What's Next?
|
||||||
|
|
||||||
|
We think Rocket provides the most productive and confidence-inspiring web
|
||||||
|
development experience in Rust today, but as always, there's room for
|
||||||
|
improvement. To that end, here's what's on the docket for the next major
|
||||||
|
release:
|
||||||
|
|
||||||
|
0. **Migration to RWF2**
|
||||||
|
|
||||||
|
Discussed further in the [RWF2 prelaunch announcement], Rocket will
|
||||||
|
transition to being managed by the newly formed Rocket Web Framework
|
||||||
|
Foundation: _RWF2_. The net effect is increased development transparency,
|
||||||
|
including public roadmaps and periodic updates, financial support for
|
||||||
|
high-quality contributions, and codified pathways into the project's
|
||||||
|
governance.
|
||||||
|
|
||||||
|
0. **Pluggable Connection Listeners**
|
||||||
|
|
||||||
|
Rocket currently expects and enjoins connection origination via
|
||||||
|
TCP/IP. While sufficient for the common case, it excludes other desirable
|
||||||
|
interfaces such as Unix Domain Sockets (UDS).
|
||||||
|
|
||||||
|
In the next major release, Rocket will expose [an interface for implementing
|
||||||
|
and plugging-in custom connection listeners]. Rocket itself will make use
|
||||||
|
of this interface to expose more common mediums out-of-the-box, such as the
|
||||||
|
aforementioned UDS.
|
||||||
|
|
||||||
|
0. **Native `async` Traits**
|
||||||
|
|
||||||
|
Given the [stabilization of `async fn` in traits], the next major release
|
||||||
|
will seek to eliminate Rocket's dependence on `#[async_trait]` opting instead
|
||||||
|
for native `async` traits. This will greatly improve our documentation, which
|
||||||
|
currently calls out the attribute for each affected trait, as well as offer
|
||||||
|
modest performance improvements.
|
||||||
|
|
||||||
|
0. [**Typed Catchers**](https://github.com/SergioBenitez/Rocket/issues/749)
|
||||||
|
|
||||||
|
Today's catchers cannot receive strictly typed error data. This results
|
||||||
|
in workarounds where error data is queried for well-typedness at runtime.
|
||||||
|
While it _has_ been possible to implement a form of typed error catching
|
||||||
|
prior, doing so necessitated limiting error data to `'static` values, as
|
||||||
|
other Rust web frameworks do, a concession we're unwilling to make.
|
||||||
|
|
||||||
|
After much experimentation, we have an approach that is ergonomic to use,
|
||||||
|
safe, and correct, all without the `'static` limitation. This will allow error
|
||||||
|
catchers to "pattern match" against error types at compile-time. At runtime,
|
||||||
|
Rocket will match emerging error types against the declared catchers and
|
||||||
|
call the appropriate catcher with the fully-typed value.
|
||||||
|
|
||||||
|
0. **Short-Circuitable Request Processing**
|
||||||
|
|
||||||
|
Whether with success or failure, fairings and guards cannot presently
|
||||||
|
terminate request processing early. The rationale for forbidding this
|
||||||
|
functionality was that it would allow third-party crates and plugins to
|
||||||
|
dictate responses without offering any recourse to the top-level application.
|
||||||
|
|
||||||
|
With the advent of typed catchers, however, we now have a mechanism by which
|
||||||
|
a top-level application can intercept early responses via their type,
|
||||||
|
resolving the prior concern. As such, in the next major release, fairings and
|
||||||
|
guards will be able to respond to requests early, and catchers will be able to
|
||||||
|
intercept those early responses at will.
|
||||||
|
|
||||||
|
0. **Associated Resources**
|
||||||
|
|
||||||
|
Often a set of routes will share a set requirements. For example, they
|
||||||
|
may share a URI prefix, subset of guards, and some managed state. In today's
|
||||||
|
Rocket, these common requirements must be repeatedly specified for each route.
|
||||||
|
While this is by design (we _want_ a route's requirements to be obvious), the
|
||||||
|
repetition is arduous and potentially error prone.
|
||||||
|
|
||||||
|
In an upcoming major release, Rocket will introduce new mechanisms by which
|
||||||
|
a set of routes can share an explicitly declared set of requirements. Their
|
||||||
|
_explicit_ and _declarative_ nature results in requirements that are
|
||||||
|
simultaneously obvious _and_ declared once.
|
||||||
|
|
||||||
|
We're really excited about this upcoming change and will be announcing more
|
||||||
|
in the near future.
|
||||||
|
|
||||||
|
0. **Performance Improvements**
|
||||||
|
|
||||||
|
Rocket appears to lag behind other Rust web frameworks in benchmarks. This is
|
||||||
|
partly due to [poor benchmarking], partly due to security-minded design
|
||||||
|
decisions, and partially due to unexploited opportunities. In the next
|
||||||
|
release, we'll be addressing the latter points. Specifically:
|
||||||
|
|
||||||
|
- _Explore making work stealing optional._
|
||||||
|
|
||||||
|
Rocket currently defaults to using tokio's multithreaded, work-stealing
|
||||||
|
scheduler. This avoids tail latency issues when faced with irregular and
|
||||||
|
heterogeneous tasks at the expense of throughput due to higher bookkeeping costs
|
||||||
|
associated with work stealing. Other Rust web frameworks instead opt to use
|
||||||
|
tokio's single-threaded scheduler, which while theoretically suboptimal,
|
||||||
|
may yield better performance results in practice, especially when
|
||||||
|
benchmarking homogeneous workloads.
|
||||||
|
|
||||||
|
While we believe work-stealing schedulers are the right choice for the
|
||||||
|
majority of applications desireing robust performance characteristics, we also
|
||||||
|
believe the choice should be the user's. We'll seek to make this choice
|
||||||
|
easier in the next release.
|
||||||
|
|
||||||
|
- _Reduce conversions from external to internal HTTP types._
|
||||||
|
|
||||||
|
Rocket revalidates and sometimes copies incoming HTTP request data.
|
||||||
|
In Rocket v0.5, we began transitioning to a model where we revalidate
|
||||||
|
security insensitive data in debug mode only, allowing for bugs to be
|
||||||
|
caught and reported while reducing performance impacts in production. In
|
||||||
|
the next release, we seek to extend this approach.
|
||||||
|
|
||||||
|
[an interface for implementing and plugging-in custom connection listeners]:
|
||||||
|
https://github.com/SergioBenitez/Rocket/issues/1070#issuecomment-1491101952
|
||||||
|
[stabilization of `async fn` in traits]: https://github.com/rust-lang/rust/pull/115822
|
||||||
|
[poor benchmarking]: @guide/faq/#performance
|
||||||
|
|
||||||
|
<!-- custom routers? -->
|
||||||
|
|
||||||
|
## ❤️ Thank You
|
||||||
|
|
||||||
|
A very special thank you to [Jeb Rosen], Rocket's maintainer from v0.4 to
|
||||||
|
v0.5-rc.1, without whom Rocket v0.5 wouldn't exist. Jeb is responsible for
|
||||||
|
leading the migration to `async` and Rust stable along with tireless efforts to
|
||||||
|
improve Rocket's documentation and address the community. Rocket is better for
|
||||||
|
having had Jeb along for the ride. Thank you, Jeb.
|
||||||
|
|
||||||
|
[Jeb Rosen]: https://github.com/SergioBenitez/Rocket/commits?author=jebrosen
|
||||||
|
|
||||||
|
A special thank you to all of Rocket's users, especially those who diligently
|
||||||
|
waded through all four release candidates, raised issues, and participated on
|
||||||
|
[GitHub] and the [Matrix channel]. You all are an awesome, kind, and thoughtful
|
||||||
|
bunch. Thank you.
|
||||||
|
|
||||||
|
A heartfelt _thank you_ as well to _all_ **148** who contributed to Rocket v0.5:
|
||||||
|
|
||||||
|
<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>Benjamin B</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>cui fliter</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>Fenhl</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>Jieyou Xu</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>Lev Kokotov</li>
|
||||||
|
<li>lewis</li>
|
||||||
|
<li>Lionel G</li>
|
||||||
|
<li>Lucille Blumire</li>
|
||||||
|
<li>Mai-Lapyst</li>
|
||||||
|
<li>Manuel</li>
|
||||||
|
<li>Manuel Transfeld</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>Riley Patterson</li>
|
||||||
|
<li>Rodolphe Bréard</li>
|
||||||
|
<li>Roger Mo</li>
|
||||||
|
<li>RotesWasser</li>
|
||||||
|
<li>rotoclone</li>
|
||||||
|
<li>Ruben Schmidmeister</li>
|
||||||
|
<li>Rudi Floren</li>
|
||||||
|
<li>Rémi Lauzier</li>
|
||||||
|
<li>Samuele Esposito</li>
|
||||||
|
<li>Scott McMurray</li>
|
||||||
|
<li>Sergio Benitez</li>
|
||||||
|
<li>Silas Sewell</li>
|
||||||
|
<li>Soham Roy</li>
|
||||||
|
<li>Steven Murdoch</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>Unpublished</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>
|
||||||
|
|
||||||
|
[GitHub discussions]: https://github.com/SergioBenitez/Rocket/discussions
|
||||||
|
[Matrix channel]: https://chat.mozilla.org/#/room/#rocket:mozilla.org
|
||||||
|
|
||||||
|
## Get Involved
|
||||||
|
|
||||||
|
Looking to help with Rocket? To contribute code, head over to [GitHub]. To get
|
||||||
|
involved with the project, see the [RWF2 prelaunch announcement]. We'd love to have you.
|
||||||
|
|
||||||
|
[GitHub]: https://github.com/SergioBenitez/Rocket
|
||||||
|
[RWF2 prelaunch announcement]: ../2023-11-17-rwf2-prelaunch/
|
|
@ -1,17 +1,30 @@
|
||||||
[[articles]]
|
[[articles]]
|
||||||
title = """
|
title = """
|
||||||
Rocket v0.5: Stable, Async, Featureful
|
Rocket v0.5: Stable, Async, Feature Packed
|
||||||
"""
|
"""
|
||||||
slug = "2023-05-26-version-0.5"
|
slug = "2023-11-17-version-0.5"
|
||||||
author = "Sergio Benitez"
|
author = "Sergio Benitez"
|
||||||
author_url = "https://sergio.bz"
|
author_url = "https://sergio.bz"
|
||||||
date = "May 26, 2023"
|
date = "Nov 17, 2023"
|
||||||
snippet = """
|
snippet = """
|
||||||
I am _elated_ to announce that Rocket v0.5 is generally available. A step
|
I am _elated_ to announce that Rocket v0.5 is now generally available. A step
|
||||||
forward in every direction, it is **packed** with features and improvements that
|
forward in every direction, it is **packed** with features and improvements that
|
||||||
increase developer productivity, improve application security and robustness,
|
increase developer productivity, improve application security and robustness,
|
||||||
provide new opportunities for extensibility, and deliver a renewed degree of
|
provide new opportunities for extensibility, and afford toolchain stability.
|
||||||
toolchain stability.
|
"""
|
||||||
|
|
||||||
|
[[articles]]
|
||||||
|
title = """
|
||||||
|
Building a Better Foundation for Rocket's Future
|
||||||
|
"""
|
||||||
|
slug = "2023-11-17-rwf2-prelaunch"
|
||||||
|
author = "Sergio Benitez"
|
||||||
|
author_url = "https://sergio.bz"
|
||||||
|
date = "Nov 17, 2023"
|
||||||
|
snippet = """
|
||||||
|
Today I'm excited to share plans to launch the Rocket Web Framework Foundation
|
||||||
|
(RWF2), a 501(c)(3) nonprofit and collective to support Rocket and the
|
||||||
|
surrounding ecosystem.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
[[articles]]
|
[[articles]]
|
||||||
|
|
Loading…
Reference in New Issue