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]
|
||||
version = "0.5.0"
|
||||
date = "Nov XX, 2023"
|
||||
date = "Nov 17, 2023"
|
||||
|
||||
###############################################################################
|
||||
# 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]]
|
||||
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]]
|
||||
|
|
Loading…
Reference in New Issue