Polish news for v0.5. Add RWF2 announcement.

This commit is contained in:
Sergio Benitez 2023-11-12 17:21:46 -08:00
parent ba9f77643f
commit 64cf1ee79e
5 changed files with 899 additions and 332 deletions

View File

@ -4,7 +4,7 @@
[release]
version = "0.5.0"
date = "Nov XX, 2023"
date = "Nov 17, 2023"
###############################################################################
# Top features: displayed in the header under the introductory text.

View File

@ -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?

View File

@ -0,0 +1,256 @@
# 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 the release of Rocket v0.5].
[along with the 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. Initially, 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. While I couldn't control the life events that pulled me
away from Rocket and most of my responsibilities, I could have done more to
communicate. 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. And I'm truly, sincerely sorry. I let you
down, and for that I apologize.
## 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 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, though certainly not limited to, 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 via GitHub ahead of
schedule. Thank you!
0. **Team Assembly**
At least initially, RWF2 governance will be 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 related projects. 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
In the near future, we also want to realize the following:
* **µ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**
Another 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 hope you'll join me in making the RWF2 a success. And in case you missed it,
check out the [release of Rocket v0.5]! We look forward to seeing you again soon
with updates on the RWF2's progress.

View File

@ -0,0 +1,623 @@
# 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/

View File

@ -1,17 +1,30 @@
[[articles]]
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_url = "https://sergio.bz"
date = "May 26, 2023"
date = "Nov 17, 2023"
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
increase developer productivity, improve application security and robustness,
provide new opportunities for extensibility, and deliver a renewed degree of
toolchain stability.
provide new opportunities for extensibility, and afford 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]]