From 2b8d6d3f06d8b1f330b6cbcf3bd821ec370a660c Mon Sep 17 00:00:00 2001 From: Sergio Benitez Date: Wed, 22 Nov 2023 21:38:53 +0100 Subject: [PATCH] Update data for site refresh. --- site/guide/5-responses.md | 38 ++++++ site/index.toml | 265 +++++++++++++++++++++++++++++++++----- site/overview.toml | 160 ----------------------- 3 files changed, 273 insertions(+), 190 deletions(-) diff --git a/site/guide/5-responses.md b/site/guide/5-responses.md index 831b31ac..8a1fc468 100644 --- a/site/guide/5-responses.md +++ b/site/guide/5-responses.md @@ -421,6 +421,44 @@ how to detect and handle graceful shutdown requests. [`EventStream`]: @api/rocket/response/stream/struct.EventStream.html [`chat` example]: @example/chat +### WebSockets + +Enabled by Rocket's support for [HTTP connection upgrades], the official +[`rocket_ws`] crate implements first-class support for WebSockets. 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) +} +``` + +As with `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. + +[HTTP connection upgrades]: @api-v0.5/rocket/response/struct.Response.html#upgrading +[`rocket_ws`]: @api-v0.5/rocket_ws + ### JSON The [`Json`] responder in allows you to easily respond with well-formed JSON diff --git a/site/index.toml b/site/index.toml index b722b5c6..f3e1db77 100644 --- a/site/index.toml +++ b/site/index.toml @@ -12,14 +12,14 @@ date = "Nov 17, 2023" [[top_features]] title = "Type Safe" -text = "From request to response Rocket ensures that your types mean something." +text = "Type safety turned up to 11 means security and robustness come at compile-time." image = "helmet" button = "Learn More" url = "overview/#how-rocket-works" [[top_features]] title = "Boilerplate Free" -text = "Spend your time writing code that really matters, and let Rocket generate the rest." +text = "Spend your time writing code that really matters and let Rocket handle the rest." image = "robot-free" button = "See Examples" url = "overview/#anatomy-of-a-rocket-application" @@ -66,7 +66,7 @@ text = ''' Hello, 58 year old named John! If someone visits a path with an `` that isn’t a `u8`, Rocket doesn’t - blindly call `hello`. Instead, it tries other matching routes or returns a + just call `hello`. Instead, it tries other matching routes or returns a **404**. ''' @@ -91,14 +91,14 @@ text = ''' `data` parameter to a `Form` type. Rocket automatically **parses and validates** the form data into your structure and calls your function. + File uploads? A breeze with [`TempFile`](@api/rocket/fs/enum.TempFile.html). Bad form request? Rocket doesn’t call your function! Need to know what went wrong? Use a `data` parameter of `Result`! Want to rerender the form with user - input and errors? Use [`Context`](guide/requests/#context)! File uploads? A - breeze with [`TempFile`](@api/rocket/fs/enum.TempFile.html). + input and errors? Use [`Context`](guide/requests/#context)! ''' [[sections]] -title = "JSON, out of the box." +title = "JSON, always on." code = ''' #[derive(Serialize, Deserialize)] struct Message<'r> { @@ -145,11 +145,11 @@ text = "View, add, or remove cookies, with or without encryption, without hassle image = 'cookies-icon' url = 'guide/requests/#cookies' button = 'Learn More' -color = 'purple' +color = 'fucsia' margin = -6 [[bottom_features]] -title = 'Async Streams' +title = 'WebSockets + Streams' text = "Create and return potentially infinite async streams of data with ease." image = 'streams-icon' url = 'guide/responses/#async-streams' @@ -167,35 +167,240 @@ color = 'yellow' margin = -3 [[bottom_features]] -title = 'Testing Library' -text = "Unit test your applications with ease using the built-in testing library." -image = 'testing-icon' -url = 'guide/testing#testing' +title = 'Type-Checked URIs' +text = "Never mistype or forget to update a URI again with Rocket's typed URIs." +image = 'pencil-icon' +url = 'guide/requests/#private-cookies' button = 'Learn More' color = 'orange' +height = '60px' +margin = -3 [[bottom_features]] -title = 'Typed URIs' -text = "Rocket typechecks route URIs for you so you never mistype a URI again." +title = 'Structured Middleware' +text = "Fairings are Rocket's simpler approach to structured middleware." image = 'ship-icon' -url = 'guide/responses/#typed-uris' +url = 'guide/fairings/#fairings' button = 'Learn More' color = 'green' margin = -20 -# [[bottom_features]] -# title = 'Query Strings' -# text = "Handling query strings and parameters is type-safe and easy in Rocket." -# image = 'query-icon' -# url = 'guide/requests/#query-strings' -# button = 'Learn More' -# color = 'red' -# margin = -3 +[[bottom_features]] +title = 'Database Support' +text = "Store data with ease with Rocket's built-in ORM agnostic database support." +image = 'query-icon' +url = 'guide/state/#databases' +button = 'Learn More' +color = 'pink' +margin = -3 -# [[bottom_features]] -# title = 'Private Cookies' -# text = "Safe, secure, private cookies are built-in so your users can stay safe." -# image = 'sessions-icon' -# url = 'guide/requests/#private-cookies' -# button = 'Learn More' -# color = 'purple' +[[bottom_features]] +title = 'Testing' +text = "Unit and integration test using the comprehensive, built-in testing library." +image = 'testing-icon' +url = 'guide/testing#testing' +button = 'Learn More' +color = 'aqua' + +[[bottom_features]] +title = 'Community' +text = "Join an extensive community of 20,000+ Rocketeers that love Rocket." +image = 'globe' +url = 'https://github.com/rwf2/Rocket/network/dependents' +button = 'See Dependents' +color = 'purple' +height = '62px' + +############################################################################### +# Panels: displayed in a tabbed arrangement. +############################################################################### + +[[panels]] +name = "Routing" +checked = true +content = ''' +Rocket's main task is to route incoming requests to the appropriate request +handler using your application's declared routes. Routes are declared using +Rocket's _route_ attributes. The attribute describes the requests that match the +route. The attribute is placed on top of a function that is the request handler +for that route. + +As an example, consider the simple route below: + +```rust +#[get("/")] +fn index() -> &'static str { + "Hello, world!" +} +``` + +This `index` route matches any incoming HTTP `GET` request to `/`, the index. +The handler returns a `String`. Rocket automatically converts the string into a +well-formed HTTP response that includes the appropriate `Content-Type` and body +encoding metadata. +''' + +[[panels]] +name = "Dynamic Params" +content = ''' +Rocket automatically parses dynamic data in path segments into any desired type. +To illustrate, let's use the following route: + +```rust +#[get("/hello//")] +fn hello(name: &str, age: u8) -> String { + format!("Hello, {} year old named {}!", age, name) +} +``` + +This `hello` route has two dynamic parameters, identified with angle brackets, +declared in the route URI: `` and ``. Rocket maps each parameter to +an identically named function argument: `name: &str` and `age: u8`. The dynamic +data in the incoming request is parsed automatically into a value of the +argument's type. The route is called only when parsing succeeds. + +Parsing is directed by the +[`FromParam`](@api/rocket/request/trait.FromParam.html) trait. Rocket implements +`FromParam` for many standard types, including both `&str` and `u8`. You can +implement it for your own types, too! +''' + +[[panels]] +name = "Handling Data" +content = ''' +Rocket can automatically parse body data, too! + +```rust +#[post("/login", data = "")] +fn login(login: Form) -> String { + format!("Hello, {}!", login.name) +} +``` + +The dynamic parameter declared in the `data` route attribute parameter again +maps to a function argument. Here, `login` maps to `login: Form`. +Parsing is again trait-directed, this time by the +[`FromData`](@api/rocket/data/trait.FromData.html) trait. + +The [`Form`](@api/rocket/form/struct.Form.html) type is Rocket's [robust form +data parser](@guide/requests/#forms). It automatically parses the request body into the internal type, +here `UserLogin`. Other built-in `FromData` types include +[`Data`](@api/rocket/struct.Data.html), +[`Json`](@api/rocket/serde/json/struct.Json.html), and +[`MsgPack`](@api/rocket/serde/msgpack/struct.MsgPack.html). As always, you can +implement `FromData` for your own types, too! +''' + +[[panels]] +name = "Request Guards" +content = ''' +In addition to dynamic path and data parameters, request handlers can also +contain a third type of parameter: _request guards_. Request guards aren't +declared in the route attribute, and any number of them can appear in the +request handler signature. + +Request guards _protect_ the handler from running unless some set of conditions +are met by the incoming request metadata. For instance, if you are writing an +API that requires sensitive calls to be accompanied by an API key in the request +header, Rocket can protect those calls via a custom `ApiKey` request guard: + +```rust +#[get("/sensitive")] +fn sensitive(key: ApiKey) { ... } +``` + +`ApiKey` protects the `sensitive` handler from running incorrectly. In order for +Rocket to call the `sensitive` handler, the `ApiKey` type needs to be derived +through a [`FromRequest`](@api/rocket/request/trait.FromRequest.html) +implementation, which in this case, validates the API key header. Request guards +are a powerful and unique Rocket concept; they centralize application policy and +invariants through types. +''' + +[[panels]] +name = "Responders" +content = ''' +The return type of a request handler can be any type that implements +[`Responder`](@api/rocket/response/trait.Responder.html): + +```rust +#[get("/")] +fn route() -> T { ... } +``` + +Above, T must implement `Responder`. Rocket implements `Responder` for many of +the standard library types including `&str`, `String`, `File`, `Option`, and +`Result`. Rocket also implements custom responders such as +[`Redirect`](@api/rocket/response/struct.Redirect.html), +[`Flash`](@api/rocket/response/struct.Flash.html), and +[`Template`](@api/rocket_dyn_templates/struct.Template.html). + +The task of a `Responder` is to generate a +[`Response`](@api/rocket/response/struct.Response.html), if possible. +`Responder`s can fail with a status code. When they do, Rocket calls the +corresponding error catcher, a `catch` route, which can be declared as follows: + +```rust +#[catch(404)] +fn not_found() -> T { ... } +``` +''' + +[[panels]] +name = "Launching" +content = ''' +Finally, we get to launch our application! Rocket begins dispatching requests to +routes after they've been _mounted_ and the application has been _launched_. +These two steps, usually wrtten in a `rocket` function, look like: + +```rust +#[launch] +fn rocket() -> _ { + rocket::build().mount("/base", routes![index, another]) +} +``` + +The `mount` call takes a _base_ and a set of routes via the `routes!` macro. The +base path (`/base` above) is prepended to the path of every route in the list, +effectively namespacing the routes. `#[launch]` creates a `main` function that +starts the server. In development, Rocket prints useful information to the +console to let you know everything is okay. + +```sh +🚀 Rocket has launched from http://127.0.0.1:8000 +``` +''' + +############################################################################### +# Sponsors +############################################################################### + +[sponsors.diamond] +name = "💎 Diamond" +tag = "$500/month" +color = "#addcde" +height = "70px" + +[sponsors.gold] +name = "💛 Gold" +tag = "$250/month" +color = "#fffbba" +height = "55px" + +[[sponsors.gold.sponsors]] +name = "ohne-makler" +url = "https://www.ohne-makler.net/" +img = "ohne-makler.svg" + +[[sponsors.gold.sponsors]] +name = "RWF2: Rocket Web Framework Foundation" +url = "https://rwf2.org" +img = "rwf2.gif" +width = "55px" +height = "55px" + +[sponsors.bronze] +name = "🤎 Bronze" +tag = "$50/month" +color = "#c5a587" +height = "30px" diff --git a/site/overview.toml b/site/overview.toml index c37384c3..204c3671 100644 --- a/site/overview.toml +++ b/site/overview.toml @@ -1,163 +1,3 @@ -############################################################################### -# Panels: displayed in a tabbed arrangement. -############################################################################### - -[[panels]] -name = "Routing" -checked = true -content = ''' -Rocket's main task is to route incoming requests to the appropriate request -handler using your application's declared routes. Routes are declared using -Rocket's _route_ attributes. The attribute describes the requests that match the -route. The attribute is placed on top of a function that is the request handler -for that route. - -As an example, consider the simple route below: - -```rust -#[get("/")] -fn index() -> &'static str { - "Hello, world!" -} -``` - -This `index` route matches any incoming HTTP `GET` request to `/`, the index. -The handler returns a `String`. Rocket automatically converts the string into a -well-formed HTTP response that includes the appropriate `Content-Type` and body -encoding metadata. -''' - -[[panels]] -name = "Dynamic Params" -content = ''' -Rocket automatically parses dynamic data in path segments into any desired type. -To illustrate, let's use the following route: - -```rust -#[get("/hello//")] -fn hello(name: &str, age: u8) -> String { - format!("Hello, {} year old named {}!", age, name) -} -``` - -This `hello` route has two dynamic parameters, identified with angle brackets, -declared in the route URI: `` and ``. Rocket maps each parameter to -an identically named function argument: `name: &str` and `age: u8`. The dynamic -data in the incoming request is parsed automatically into a value of the -argument's type. The route is called only when parsing succeeds. - -Parsing is directed by the -[`FromParam`](@api/rocket/request/trait.FromParam.html) trait. Rocket implements -`FromParam` for many standard types, including both `&str` and `u8`. You can -implement it for your own types, too! -''' - -[[panels]] -name = "Handling Data" -content = ''' -Rocket can automatically parse body data, too! - -```rust -#[post("/login", data = "")] -fn login(login: Form) -> String { - format!("Hello, {}!", login.name) -} -``` - -The dynamic parameter declared in the `data` route attribute parameter again -maps to a function argument. Here, `login` maps to `login: Form`. -Parsing is again trait-directed, this time by the -[`FromData`](@api/rocket/data/trait.FromData.html) trait. - -The [`Form`](@api/rocket/form/struct.Form.html) type is Rocket's [robust form -data parser](@guide/requests/#forms). It automatically parses the request body into the internal type, -here `UserLogin`. Other built-in `FromData` types include -[`Data`](@api/rocket/struct.Data.html), -[`Json`](@api/rocket/serde/json/struct.Json.html), and -[`MsgPack`](@api/rocket/serde/msgpack/struct.MsgPack.html). As always, you can -implement `FromData` for your own types, too! -''' - -[[panels]] -name = "Request Guards" -content = ''' -In addition to dynamic path and data parameters, request handlers can also -contain a third type of parameter: _request guards_. Request guards aren't -declared in the route attribute, and any number of them can appear in the -request handler signature. - -Request guards _protect_ the handler from running unless some set of conditions -are met by the incoming request metadata. For instance, if you are writing an -API that requires sensitive calls to be accompanied by an API key in the request -header, Rocket can protect those calls via a custom `ApiKey` request guard: - -```rust -#[get("/sensitive")] -fn sensitive(key: ApiKey) { ... } -``` - -`ApiKey` protects the `sensitive` handler from running incorrectly. In order for -Rocket to call the `sensitive` handler, the `ApiKey` type needs to be derived -through a [`FromRequest`](@api/rocket/request/trait.FromRequest.html) -implementation, which in this case, validates the API key header. Request guards -are a powerful and unique Rocket concept; they centralize application policy and -invariants through types. -''' - -[[panels]] -name = "Responders" -content = ''' -The return type of a request handler can be any type that implements -[`Responder`](@api/rocket/response/trait.Responder.html): - -```rust -#[get("/")] -fn route() -> T { ... } -``` - -Above, T must implement `Responder`. Rocket implements `Responder` for many of -the standard library types including `&str`, `String`, `File`, `Option`, and -`Result`. Rocket also implements custom responders such as -[`Redirect`](@api/rocket/response/struct.Redirect.html), -[`Flash`](@api/rocket/response/struct.Flash.html), and -[`Template`](@api/rocket_dyn_templates/struct.Template.html). - -The task of a `Responder` is to generate a -[`Response`](@api/rocket/response/struct.Response.html), if possible. -`Responder`s can fail with a status code. When they do, Rocket calls the -corresponding error catcher, a `catch` route, which can be declared as follows: - -```rust -#[catch(404)] -fn not_found() -> T { ... } -``` -''' - -[[panels]] -name = "Launching" -content = ''' -Finally, we get to launch our application! Rocket begins dispatching requests to -routes after they've been _mounted_ and the application has been _launched_. -These two steps, usually wrtten in a `rocket` function, look like: - -```rust -#[launch] -fn rocket() -> _ { - rocket::build().mount("/base", routes![index, another]) -} -``` - -The `mount` call takes a _base_ and a set of routes via the `routes!` macro. The -base path (`/base` above) is prepended to the path of every route in the list, -effectively namespacing the routes. `#[launch]` creates a `main` function that -starts the server. In development, Rocket prints useful information to the -console to let you know everything is okay. - -```sh -🚀 Rocket has launched from http://127.0.0.1:8000 -``` -''' - ############################################################################### # Steps to "How Rocket Works" ###############################################################################