Rocket Responders
Some of Rocket’s best features are implemented through responders. You can find many of these responders in the response module. Among these are:
- Content - Used to override the Content-Type of a response.
- NamedFile - Streams a file to the client; automatically sets the Content-Type based on the file’s extension.
- Redirect - Redirects the client to a different URI.
- Stream - Streams a response to a client from an arbitrary
Read
er type. - status - Contains types that override the status code of a response.
- Flash - Sets a “flash” cookie that is removed when accessed.
Streaming
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 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, to stream from a local Unix stream, we might write:
#[get("/stream")]
fn stream() -> io::Result<Stream<UnixStream>> {
UnixStream::connect("/path/to/my/socket").map(|s| Stream::from(s))
}
JSON
The JSON responder in rocket_contrib allows you to easily respond with well-formed JSON data: simply return a value of type Json<T>
where T
is the type of a structure to serialize into JSON. The type T
must implement the Serialize trait from serde, which can be automatically derived.
As an example, to respond with the JSON value of a Task
structure, we might write:
use rocket_contrib::Json;
#[derive(Serialize)]
struct Task { ... }
#[get("/todo")]
fn todo() -> Json<Task> { ... }
The JSON
type serializes the structure into JSON, sets the Content-Type to JSON, and emits the serialized data in a fixed-sized body. If serialization fails, a 500 - Internal Server Error is returned.
The JSON example on GitHub provides further illustration.
Templates
Rocket includes built-in templating support that works largely through a Template responder in rocket_contrib
. To render a template named “index”, for instance, you might return a value of type Template
as follows:
#[get("/")]
fn index() -> Template {
let context = /* object-like value */;
Template::render("index", &context)
}
Templates are rendered with the render
method. The method takes in the name of a template and a context to render the template with. The context can be any type that implements Serialize
and serializes into an Object
value, such as structs, HashMaps
, and others.
Rocket searches for a template with the given name in the configurable template_dir
directory. Templating support in Rocket is engine agnostic. The engine used to render a template depends on the template file’s extension. For example, if a file ends with .hbs
, Handlebars is used, while if a file ends with .tera
, Tera is used.
For templates to be properly registered, the template fairing must be attached to the instance of Rocket. The Fairings sections of the guide provides more information on fairings. To attach the template fairing, simply call .attach(Template::fairing())
on an instance of Rocket
as follows:
fn main() {
rocket::ignite()
.mount("/", routes![...])
.attach(Template::fairing());
}
The Template API documentation contains more information about templates, while the Handlebars Templates example on GitHub is a fully composed application that makes use of Handlebars templates.