Update the guide for async-related API changes.

This commit is contained in:
Jeb Rosen 2020-01-08 08:03:05 -08:00 committed by Sergio Benitez
parent 85761c08e3
commit f2487ccec5
6 changed files with 37 additions and 26 deletions

View File

@ -216,10 +216,11 @@ For the `upload` route, we'll need to `use` a few items:
```rust ```rust
use std::io; use std::io;
use std::path::Path; use std::path::PathBuf;
use rocket::Data; use rocket::Data;
use rocket::http::RawStr; use rocket::http::RawStr;
use rocket::response::Debug;
``` ```
The [Data](@api/rocket/data/struct.Data.html) structure is key The [Data](@api/rocket/data/struct.Data.html) structure is key
@ -279,7 +280,7 @@ fn upload(paste: Data) -> Result<String, Debug<std::io::Error>> {
let url = format!("{host}/{id}\n", host = "http://localhost:8000", id = id); let url = format!("{host}/{id}\n", host = "http://localhost:8000", id = id);
// Write the paste out to the file and return the URL. // Write the paste out to the file and return the URL.
paste.stream_to_file(Path::new(&filename))?; paste.stream_to_file(PathBuf::from(filename)).await?;
Ok(url) Ok(url)
} }
``` ```

View File

@ -412,7 +412,7 @@ imply, a request guard protects a handler from being called erroneously based on
information contained in an incoming request. More specifically, a request guard information contained in an incoming request. More specifically, a request guard
is a type that represents an arbitrary validation policy. The validation policy is a type that represents an arbitrary validation policy. The validation policy
is implemented through the [`FromRequest`] trait. Every type that implements is implemented through the [`FromRequest`] trait. Every type that implements
`FromRequest` is a request guard. `FromRequest` (or the related [`FromRequestAsync`]) is a request guard.
Request guards appear as inputs to handlers. An arbitrary number of request Request guards appear as inputs to handlers. An arbitrary number of request
guards can appear as arguments in a route handler. Rocket will automatically guards can appear as arguments in a route handler. Rocket will automatically
@ -444,6 +444,7 @@ more about request guards and implementing them, see the [`FromRequest`]
documentation. documentation.
[`FromRequest`]: @api/rocket/request/trait.FromRequest.html [`FromRequest`]: @api/rocket/request/trait.FromRequest.html
[`FromRequestAsync`]: @api/rocket/request/trait.FromRequestAsync.html
[`Cookies`]: @api/rocket/http/enum.Cookies.html [`Cookies`]: @api/rocket/http/enum.Cookies.html
### Custom Guards ### Custom Guards

View File

@ -299,8 +299,8 @@ library. Among these are:
The `Stream` type deserves special attention. When a large amount of data needs The `Stream` type deserves special attention. When a large amount of data needs
to be sent to the client, it is better to stream the data to the client to avoid to be sent to the client, it is better to stream the data to the client to avoid
consuming large amounts of memory. Rocket provides the [`Stream`] type, making consuming large amounts of memory. Rocket provides the [`Stream`] type, making
this easy. The `Stream` type can be created from any `Read` type. For example, this easy. The `Stream` type can be created from any `AsyncRead` type. For
to stream from a local Unix stream, we might write: example, to stream from a local Unix stream, we might write:
```rust ```rust
# #[macro_use] extern crate rocket; # #[macro_use] extern crate rocket;

View File

@ -203,6 +203,7 @@ request-local state to implement request timing.
[`FromRequest` request-local state]: @api/rocket/request/trait.FromRequest.html#request-local-state [`FromRequest` request-local state]: @api/rocket/request/trait.FromRequest.html#request-local-state
[`Fairing`]: @api/rocket/fairing/trait.Fairing.html#request-local-state [`Fairing`]: @api/rocket/fairing/trait.Fairing.html#request-local-state
<!-- TODO.async: rewrite? -->
## Databases ## Databases
Rocket includes built-in, ORM-agnostic support for databases. In particular, Rocket includes built-in, ORM-agnostic support for databases. In particular,

View File

@ -175,22 +175,24 @@ impl Fairing for Counter {
}; };
} }
fn on_response(&self, request: &Request, response: &mut Response) { fn on_response<'a>(&'a self, request: &'a Request<'_>, response: &'a mut Response<'_>) -> BoxFuture<'a, ()> {
// Don't change a successful user's response, ever. Box::pin(async move {
if response.status() != Status::NotFound { // Don't change a successful user's response, ever.
return if response.status() != Status::NotFound {
} return
}
// Rewrite the response to return the current counts. // Rewrite the response to return the current counts.
if request.method() == Method::Get && request.uri().path() == "/counts" { if request.method() == Method::Get && request.uri().path() == "/counts" {
let get_count = self.get.load(Ordering::Relaxed); let get_count = self.get.load(Ordering::Relaxed);
let post_count = self.post.load(Ordering::Relaxed); let post_count = self.post.load(Ordering::Relaxed);
let body = format!("Get: {}\nPost: {}", get_count, post_count); let body = format!("Get: {}\nPost: {}", get_count, post_count);
response.set_status(Status::Ok); response.set_status(Status::Ok);
response.set_header(ContentType::Plain); response.set_header(ContentType::Plain);
response.set_sized_body(Cursor::new(body)); response.set_sized_body(Cursor::new(body));
} }
})
} }
} }
``` ```
@ -220,9 +222,9 @@ rocket::ignite()
.attach(AdHoc::on_launch("Launch Printer", |_| { .attach(AdHoc::on_launch("Launch Printer", |_| {
println!("Rocket is about to launch! Exciting! Here we go..."); println!("Rocket is about to launch! Exciting! Here we go...");
})) }))
.attach(AdHoc::on_request("Put Rewriter", |req, _| { .attach(AdHoc::on_request("Put Rewriter", |req, _| Box::pin(async move {
req.set_method(Method::Put); req.set_method(Method::Put);
})); })));
``` ```
[`AdHoc`]: @api/rocket/fairing/struct.AdHoc.html [`AdHoc`]: @api/rocket/fairing/struct.AdHoc.html

View File

@ -103,7 +103,7 @@ use rocket::http::{ContentType, Status};
let rocket = rocket::ignite().mount("/", routes![hello]); let rocket = rocket::ignite().mount("/", routes![hello]);
let client = Client::new(rocket).expect("valid rocket instance"); let client = Client::new(rocket).expect("valid rocket instance");
let mut response = client.get("/").dispatch(); let mut response = client.get("/").dispatch().await;
assert_eq!(response.status(), Status::Ok); assert_eq!(response.status(), Status::Ok);
assert_eq!(response.content_type(), Some(ContentType::Plain)); assert_eq!(response.content_type(), Some(ContentType::Plain));
@ -167,7 +167,13 @@ You can also move the body of the `test` module into its own file, say
### Testing ### Testing
To test our "Hello, world!" application, we first create a `Client` for our First, note the `#[rocket::async_test]` attribute. Rust does not support `async
fn` for tests, so an asynchronous runtime needs to be set up. In most
applications this is done by `launch()`, but we are deliberately not calling
that in tests! Instead, we use `#[rocket::async_test]`, which runs the test
inside a runtime.
To test our "Hello, world!" application, we create a `Client` for our
`Rocket` instance. It's okay to use methods like `expect` and `unwrap` during `Rocket` instance. It's okay to use methods like `expect` and `unwrap` during
testing: we _want_ our tests to panic when something goes wrong. testing: we _want_ our tests to panic when something goes wrong.
@ -211,7 +217,7 @@ use rocket::http::{ContentType, Status};
# let mut response = client.get("/").dispatch(); # let mut response = client.get("/").dispatch();
assert_eq!(response.status(), Status::Ok); assert_eq!(response.status(), Status::Ok);
assert_eq!(response.body_string(), Some("Hello, world!".into())); assert_eq!(response.body_string().await, Some("Hello, world!".into()));
``` ```
That's it! Altogether, this looks like: That's it! Altogether, this looks like:
@ -242,9 +248,9 @@ mod test {
# */ pub # */ pub
fn hello_world() { fn hello_world() {
let client = Client::new(rocket()).expect("valid rocket instance"); let client = Client::new(rocket()).expect("valid rocket instance");
let mut response = client.get("/").dispatch(); let mut response = client.get("/").dispatch().await;
assert_eq!(response.status(), Status::Ok); assert_eq!(response.status(), Status::Ok);
assert_eq!(response.body_string(), Some("Hello, world!".into())); assert_eq!(response.body_string().await, Some("Hello, world!".into()));
} }
} }