Implementations
Rocket implements Responder
for many types in Rust’s standard library including String
, &str
, File
, Option
, and Result
. The Responder documentation describes these in detail, but we briefly cover a few here.
Strings
The Responder
implementations for &str
and String
are straight-forward: the string is used as a sized body, and the Content-Type of the response is set to text/plain
. To get a taste for what such a Responder
implementation looks like, here’s the implementation for String
:
impl Responder<'static> for String {
fn respond_to(self, _: &Request) -> Result<Response<'static>, Status> {
Response::build()
.header(ContentType::Plain)
.sized_body(Cursor::new(self))
.ok()
}
}
Because of these implementations, you can directly return an &str
or String
type from a handler:
#[get("/string")]
fn handler() -> &'static str {
"Hello there! I'm a string!"
}
Option
Option
is wrapping responder: an Option<T>
can only be returned when T
implements Responder
. If the Option
is Some
, the wrapped responder is used to respond to the client. Otherwise, a error of 404 - Not Found is returned to the client.
This implementation makes Option
a convenient type to return when it is not known until process-time whether content exists. For example, because of Option
, we can implement a file server that returns a 200
when a file is found and a 404
when a file is not found in just 4, idiomatic lines:
#[get("/<file..>")]
fn files(file: PathBuf) -> Option<NamedFile> {
NamedFile::open(Path::new("static/").join(file)).ok()
}
Result
Result
is a special kind of wrapping responder: its functionality depends on whether the error type E
implements Responder
.
When the error type E
implements Responder
, the wrapped Responder
in Ok
or Err
, whichever it might be, is used to respond to the client. This means that the responder can be chosen dynamically at run-time, and two different kinds of responses can be used depending on the circumstances. Revisiting our file server, for instance, we might wish to provide more feedback to the user when a file isn’t found. We might do this as follows:
use rocket::response::status::NotFound;
#[get("/<file..>")]
fn files(file: PathBuf) -> Result<NamedFile, NotFound<String>> {
let path = Path::new("static/").join(file);
NamedFile::open(&path).map_err(|_| NotFound(format!("Bad path: {}", path)))
}
If the error type E
does not implement Responder
, then the error is simply logged to the console, using its Debug
implementation, and a 500
error is returned to the client.