mirror of https://github.com/rwf2/Rocket.git
Update the guide for async-related API changes.
This commit is contained in:
parent
85761c08e3
commit
f2487ccec5
|
@ -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)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue