mirror of https://github.com/rwf2/Rocket.git
Improve wrapping responders guide section.
This commit is contained in:
parent
72c91958b7
commit
de6632ea56
|
@ -25,18 +25,20 @@ responses according to the incoming `Request` they are responding to.
|
||||||
|
|
||||||
### Wrapping
|
### Wrapping
|
||||||
|
|
||||||
Before we describe a few responders, we note that it is typical for responders
|
Responders compose by _wrapping_ (encapsulating) other responders. Naturally, we
|
||||||
to _wrap_ other responders. That is, responders can be of the following form,
|
call these _wrapping_ responders. A wrapping responder takes a response from an
|
||||||
where `R` is some type that implements `Responder`:
|
existing responder `R`, modifies it, and then returns it. They typically have
|
||||||
|
the following shape:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
struct WrappingResponder<R>(R);
|
struct WrappingResponder<R>(R);
|
||||||
```
|
```
|
||||||
|
|
||||||
A wrapping responder modifies the response returned by `R` before responding
|
Examples include `Responder`s in the [`status` module], which override the
|
||||||
with that same response. For instance, Rocket provides `Responder`s in the
|
status code of the wrapped `Responder`'s response, and `Responder`s in the
|
||||||
[`status` module](@api/master/rocket/response/status/) that override the status code of
|
[`content` module], which override the Content-Type.
|
||||||
the wrapped `Responder`. As an example, the [`Accepted`] type sets the status to
|
|
||||||
|
As a concrete example, the [`Accepted`] wrapping responder sets the status to
|
||||||
`202 - Accepted`. It can be used as follows:
|
`202 - Accepted`. It can be used as follows:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
@ -47,15 +49,17 @@ use rocket::response::status;
|
||||||
|
|
||||||
#[post("/<id>")]
|
#[post("/<id>")]
|
||||||
fn new(id: usize) -> status::Accepted<String> {
|
fn new(id: usize) -> status::Accepted<String> {
|
||||||
|
// Modifies the response generated by `String` to have a status of `202`.
|
||||||
status::Accepted(format!("id: '{}'", id))
|
status::Accepted(format!("id: '{}'", id))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Similarly, the types in the [`content` module](@api/master/rocket/response/content/)
|
Because wrapping responders are themselves responders, they too can be wrapped.
|
||||||
can be used to override the Content-Type of a response. For instance, to set the
|
This is what allows responders to compose, enabling powerful combinations of
|
||||||
Content-Type of `&'static str` to JSON, as well as setting the status code to an
|
simple primitives to form more powerful abstractions. For example, combining the
|
||||||
arbitrary one like `418 I'm a teapot`, combine [`content::RawJson`] with
|
[`content::RawJson`] and [`status::Custom`] responders allows creating a
|
||||||
[`status::Custom`]:
|
response with a Content-Type of JSON and an arbitrary status code like `418 I'm
|
||||||
|
a teapot` from an `&'static str`:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
# #[macro_use] extern crate rocket;
|
# #[macro_use] extern crate rocket;
|
||||||
|
@ -70,21 +74,25 @@ fn json() -> status::Custom<content::RawJson<&'static str>> {
|
||||||
|
|
||||||
! warning: This is _not_ the same as [`serde::json::Json`]!
|
! warning: This is _not_ the same as [`serde::json::Json`]!
|
||||||
|
|
||||||
The built-in `(Status, R)` and `(ContentType, R)` responders, where `R:
|
! note: There are simpler alternatives for setting a status and content-types.
|
||||||
Responder`, also override the `Status` and `Content-Type` of responses,
|
|
||||||
respectively:
|
|
||||||
|
|
||||||
```rust
|
The built-in `(Status, R)` and `(ContentType, R)` wrapping responders
|
||||||
# #[macro_use] extern crate rocket;
|
also override the `Status` and `Content-Type` of responses, respectively, and
|
||||||
use rocket::http::{Status, ContentType};
|
may be simpler alternatives:
|
||||||
|
|
||||||
#[get("/")]
|
```rust
|
||||||
fn json() -> (Status, (ContentType, &'static str)) {
|
# #[macro_use] extern crate rocket;
|
||||||
(Status::ImATeapot, (ContentType::JSON, "{ \"hi\": \"world\" }"))
|
use rocket::http::{Status, ContentType};
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
For pithy reusability, it is advisable to derive a [custom responder]:
|
#[get("/")]
|
||||||
|
fn json() -> (Status, (ContentType, &'static str)) {
|
||||||
|
(Status::ImATeapot, (ContentType::JSON, "{ \"hi\": \"world\" }"))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Composition through wrapping is useful when you want to change one or two
|
||||||
|
properties of an existing response. For more complex use-cases, instead consider
|
||||||
|
deriving a [custom responder]:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
# #[macro_use] extern crate rocket;
|
# #[macro_use] extern crate rocket;
|
||||||
|
@ -100,10 +108,12 @@ fn json() -> RawTeapotJson {
|
||||||
```
|
```
|
||||||
|
|
||||||
[`Accepted`]: @api/master/rocket/response/status/struct.Accepted.html
|
[`Accepted`]: @api/master/rocket/response/status/struct.Accepted.html
|
||||||
[`content::Json`]: @api/master/rocket/response/content/struct.Json.html
|
[`content::RawJson`]: @api/master/rocket/response/content/struct.RawJson.html
|
||||||
[`status::Custom`]: @api/master/rocket/response/status/struct.Custom.html
|
[`status::Custom`]: @api/master/rocket/response/status/struct.Custom.html
|
||||||
[`serde::json::Json`]: @api/master/rocket/serde/json/struct.Json.html
|
[`serde::json::Json`]: @api/master/rocket/serde/json/struct.Json.html
|
||||||
[custom responder]: #custom-responders
|
[custom responder]: #custom-responders
|
||||||
|
[`status` module]: @api/master/rocket/response/status/
|
||||||
|
[`content` module]: @api/master/rocket/response/content/
|
||||||
|
|
||||||
### Errors
|
### Errors
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue