Trait rocket::response::Responder[][src]

pub trait Responder<'r, 'o: 'r> {
    fn respond_to(self, request: &'r Request<'_>) -> Result<'o>;
}
Expand description

Trait implemented by types that generate responses for clients.

Any type that implements Responder can be used as the return type of a handler:

// This works for any `T` that implements `Responder`.
#[get("/")]
fn index() -> T { /* ... */ }

Deriving

This trait can, and largely should, be automatically derived. The derive can handle all simple cases and most complex cases, too. When deriving Responder, the first field of the annotated structure (or of each variant if an enum) is used to generate a response while the remaining fields are used as response headers:

use rocket::http::ContentType;
use rocket::serde::{Serialize, json::Json};

#[derive(Responder)]
enum Error<T> {
    #[response(status = 400)]
    Unauthorized(Json<T>),
    #[response(status = 404)]
    NotFound(Template, ContentType),
}

For full details on deriving Responder, see the Responder derive.

Provided Implementations

Rocket implements Responder for several standard library types. Their behavior is documented here. Note that the Result implementation is overloaded, allowing for two Responders to be used at once, depending on the variant.

  • &str

    Sets the Content-Type to text/plain. The string is used as the body of the response, which is fixed size and not streamed. To stream a raw string, use Stream::from(Cursor::new(string)).

  • String

    Sets the Content-Type to text/plain. The string is used as the body of the response, which is fixed size and not streamed. To stream a string, use Stream::from(Cursor::new(string)).

  • &[u8]

    Sets the Content-Type to application/octet-stream. The slice is used as the body of the response, which is fixed size and not streamed. To stream a slice of bytes, use Stream::from(Cursor::new(data)).

  • Vec<u8>

    Sets the Content-Type to application/octet-stream. The vector’s data is used as the body of the response, which is fixed size and not streamed. To stream a vector of bytes, use Stream::from(Cursor::new(vec)).

  • File

    Responds with a streamed body containing the data in the File. No Content-Type is set. To automatically have a Content-Type set based on the file’s extension, use NamedFile.

  • ()

    Responds with an empty body. No Content-Type is set.

  • Option<T>

    If the Option is Some, the wrapped responder is used to respond to the client. Otherwise, an Err with status 404 Not Found is returned and a warning is printed to the console.

  • Result<T, E>

    If the Result is Ok, the wrapped Ok responder is used to respond to the client. If the Result is Err, the wrapped Err responder is used to respond to the client.

Return Value

A Responder returns a Future whose output type is a Result<Response, Status>.

  • An Ok(Response) indicates success. The Response will be written out to the client.

  • An Err(Status) indicates failure. The error catcher for Status will be invoked to generate a response.

Implementation Tips

This section describes a few best practices to take into account when implementing Responder.

  1. Avoid Manual Implementations

    The Responder derive is a powerful mechanism that eliminates the need to implement Responder in almost all cases. We encourage you to explore using the derive before attempting to implement Responder directly. It allows you to leverage existing Responder implementations through composition, decreasing the opportunity for mistakes or performance degradation.

  2. Joining and Merging

    When chaining/wrapping other Responders, start with Response::build_from() and/or use the merge() or join() methods on the Response or ResponseBuilder struct. Ensure that you document merging or joining behavior appropriatse.

  3. Inspecting Requests

    While tempting, a Responder that varies its functionality based on the incoming request sacrifices its functionality being understood based purely on its type. By implication, gleaming the functionality of a handler from its type signature also becomes more difficult. You should avoid varying responses based on the Request value as much as possible.

Lifetimes

Responder has two lifetimes: Responder<'r, 'o: 'r>.

  • 'r bounds the reference to the &'r Request.

  • 'o bounds the returned Response<'o> to values that live at least as long as the request.

    This includes borrows from the Request itself (where 'o would be 'r as in impl<'r> Responder<'r, 'r>) as well as 'static data (where 'o would be 'static as in impl<'r> Responder<'r, 'static>).

In practice, you are likely choosing between four signatures:

// If the response contains no borrowed data.
impl<'r> Responder<'r, 'static> for A {
    fn respond_to(self, _: &'r Request<'_>) -> response::Result<'static> {
        todo!()
    }
}

// If the response borrows from the request.
impl<'r> Responder<'r, 'r> for B<'r> {
    fn respond_to(self, _: &'r Request<'_>) -> response::Result<'r> {
        todo!()
    }
}

// If the response is or wraps a borrow that may outlive the request.
impl<'r, 'o: 'r> Responder<'r, 'o> for &'o C {
    fn respond_to(self, _: &'r Request<'_>) -> response::Result<'o> {
        todo!()
    }
}

// If the response wraps an existing responder.
impl<'r, 'o: 'r, R: Responder<'r, 'o>> Responder<'r, 'o> for D<R> {
    fn respond_to(self, _: &'r Request<'_>) -> response::Result<'o> {
        todo!()
    }
}

Example

Say that you have a custom type, Person:

struct Person {
    name: String,
    age: u16
}

You’d like to use Person as a Responder so that you can return a Person directly from a handler:

#[get("/person/<id>")]
fn person(id: usize) -> Option<Person> {
    Person::from_id(id)
}

You want the Person responder to set two header fields: X-Person-Name and X-Person-Age as well as supply a custom representation of the object (Content-Type: application/x-person) in the body of the response. The following Responder implementation accomplishes this:

use std::io::Cursor;

use rocket::request::Request;
use rocket::response::{self, Response, Responder};
use rocket::http::ContentType;

impl<'r> Responder<'r, 'static> for Person {
    fn respond_to(self, req: &'r Request<'_>) -> response::Result<'static> {
        let string = format!("{}:{}", self.name, self.age);
        Response::build_from(string.respond_to(req)?)
            .raw_header("X-Person-Name", self.name)
            .raw_header("X-Person-Age", self.age.to_string())
            .header(ContentType::new("application", "x-person"))
            .ok()
    }
}

Note that the implementation could have instead been derived if structured in a slightly different manner:

use rocket::http::Header;
use rocket::response::Responder;

#[derive(Responder)]
#[response(content_type = "application/x-person")]
struct Person {
    text: String,
    name: Header<'static>,
    age: Header<'static>,
}

impl Person {
    fn new(name: &str, age: usize) -> Person {
        Person {
            text: format!("{}:{}", name, age),
            name: Header::new("X-Person-Name", name.to_string()),
            age: Header::new("X-Person-Age", age.to_string())
        }
    }
}

Required methods

Returns Ok if a Response could be generated successfully. Otherwise, returns an Err with a failing Status.

The request parameter is the Request that this Responder is responding to.

When using Rocket’s code generation, if an Ok(Response) is returned, the response will be written out to the client. If an Err(Status) is returned, the error catcher for the given status is retrieved and called to generate a final error response, which is then written out to the client.

Implementations on Foreign Types

Returns a response with Content-Type text/plain and a fixed-size body containing the string self. Always returns Ok.

Returns a response with Content-Type text/plain and a fixed-size body containing the string self. Always returns Ok.

Returns a response with Content-Type text/plain and a fixed-size body containing the string self. Always returns Ok.

Returns a response with Content-Type text/plain and a fixed-size body containing the string self. Always returns Ok.

Returns a response with Content-Type application/octet-stream and a fixed-size body containing the data in self. Always returns Ok.

Returns a response with Content-Type application/octet-stream and a fixed-size body containing the data in self. Always returns Ok.

Returns a response with Content-Type application/octet-stream and a fixed-size body containing the data in self. Always returns Ok.

Returns a response with Content-Type application/octet-stream and a fixed-size body containing the data in self. Always returns Ok.

Returns a response with a sized body for the file. Always returns Ok.

Returns a response with a sized body for the file. Always returns Ok.

Returns an empty, default Response. Always returns Ok.

Responds with the inner Responder in Cow.

If self is Some, responds with the wrapped Responder. Otherwise prints a warning message and returns an Err of Status::NotFound.

Err.

Right.

Prints a warning with the error and forwards to the 500 error catcher.

Implementors