diff --git a/docs/guide.md b/docs/guide.md deleted file mode 100644 index 641381b8..00000000 --- a/docs/guide.md +++ /dev/null @@ -1,579 +0,0 @@ -Welcome to Rocket! This is the official guide. It is designed to serve as a -starting point as a well as reference. This guide is conversational. For concise -and purely technical documentation, see the [API documentation](/API). - -------------------------------------------------------------------------------- - -# IDEA - -HAVE THIS GUIDE SERVE AS A REFERENCE AS WELL BY MARKING PIECES OF THIS GUIDE AS -'GUIDE ONLY' AND OMITTING THOSE SECTIONS WHEN SOMEONE WANTS A REFERENCE ONLY. IT -WOULD BE NEAT IF THERE WAS A LITTLE JAVASCRIPT BUTTON THAT JUST HID THE GUIDE -PARTS. - -# Guide - -Hello! By now you've gleaned that Rocket is a web framework for Rust. You also -know that it aims to be fast, easy, and flexible. It also aims to be _fun_, and -it accomplishes this by ensuring that you write as little code as needed to -accomplish your task. This guide is meant to introduce you to the core, -intermediate, and advanced concepts of Rocket. After reading this guide, you -should find yourself being _very_ productive with Rocket. - -## Audience - -Readers of this guide are assumed to have a good grasp of the Rust programming -language. Readers new to Rust are encourage to read through the [Rust -Book](https://doc.rust-lang.org/book/). This guide also assumes a basic -understanding of web application fundamentals and HTTP. - -# Foreword - -Rocket's philosophy is that a function declaration should contain all of the -necessary information to process a request. This immediately prohibits APIs -where request state is retrieved from a global context. As a result of the -locality of information, request handling is _self contained_ in Rocket: -handlers are regular functions that can be called by other code. - -Rocket also believes that all request handling information should be _typed_. -Because the web and HTTP are themselves untyped (or _stringly_ typed, as some -call it), this means that something or someone has to convert strings to native -types. Rocket does this for you with zero programming overhead. - -These two core philosophies dictate Rocket's interface, and you will find the -ideas embedded in Rocket's core features. But, enough with the boring diatribe. -Let's get to know Rocket. - -# Quick Start - -The absolute fastest way to start experimenting with Rocket is to clone the -Rocket repository and run the included examples. For instance, the following set -of commands runs the `hello_world` example: - -```sh -git clone https://github.com/SergioBenitez/rocket -cd rocket/examples/hello_world -cargo run -``` - -There are numerous examples in `rocket/examples`, all of which can be run with -Cargo by using `cargo run`. Note that Rocket requires the latest Rust nightly. - -# Getting Started - -Let's create and run our first Rocket application. We'll ensure we have a -compatible version of Rust, create a new Cargo project that uses Rocket, and -then run the project. - -## Rust - -Rocket makes heavy use of Rust's syntax extensions. Because syntax extension -don't yet have a stable compiler API, we'll need to use a nightly version of -Rust with Rocket. If you already have a working installation of the latest Rust -nightly, feel free to skip this section. - -To install a nightly version of Rust, we recommend using `rustup`. Install -`rustup` by following the instructions on [their website](https://rustup.rs/). -Once `rustup` is installed, configure Rust nightly as your default toolchain by -running the command: - -```sh -rustup default nightly -``` - -If you prefer, once we setup a project directory in the following section, you -can use per-directory defaults to use the nightly version _only_ for your Rocket -project by running the following command in the directory: - -```sh -rustup override set nightly -``` - -Rocket requires the latest version of Rust nightly. If your Rocket application -suddently stops building, ensure you're using the latest version of Rust by -updating: - -```sh -rustup update -``` - -## Creating a Rocket Project - -Start by creating a new binary-based Cargo project and changing into the new -directory: - -```sh -cargo new hello-rocket --bin -cd hello-rocket -``` - -Now, add Rocket and its code generation facilities to your project by ensuring -your `Cargo.toml` file contains the following dependencies: - -``` -[dependencies] -rocket = "*" -rocket_codegen = "*" -``` - -Build the project now to ensure your Rust version is compatible with the latest -Rocket version: - -```sh -cargo build -``` - -Modify `src/main.rs` so that it contains the code for the Rocket `Hello, world!` -program, which we reproduce below: - -```rust -#![feature(plugin)] -#![plugin(rocket_codegen)] - -extern crate rocket; - -#[get("/")] -fn hello() -> &'static str { - "Hello, world!" -} - -fn main() { - rocket::ignite().mount("/hello", routes![hello]).launch(); -} -``` - -Run the program by using `cargo run`. You should see the following in your -terminal: - -```sh -πŸ”§ Configured for development. - => listening: localhost:8000 - => logging: Normal - => session key: false -πŸ›° Mounting '/hello': - => GET /hello/ -πŸš€ Rocket has launched from localhost:8000... -``` - -Finally, visit `http://localhost:8000` to see your first Rocket application in -action. - -# Introduction - -Rocket provides a focused number of core primitives to build web servers and -applications with Rust: the rest is up to you. In short, Rocket provides -routing, pre-processing of requests, and post-processing of responses. Your -application code fills the gap between pre-processing and post-processing. - -Rocket _does not_ force decisions on you. Templates, serialization, sessions, -and just about everything else are all pluggable, optional components. While -Rocket has official support and libraries for each of these, they are completely -optional to use, and writing your own versions of these is not only possible, -but straightforward. These components feel like first-class citizens. - -If you'd like, you can think of Rocket as being a more flexible, friendly medley -of [Rails](rubyonrails.org), [Flask](http://flask.pocoo.org/), -[Bottle](http://bottlepy.org/docs/dev/index.html), and -[Yesod](http://www.yesodweb.com/), except without all of the bloat. We prefer to -think of Rocket as something new. - -# Routes and Handlers - -Rocket applications are centered around routes and handlers. - -A _handler_ is simply a function that takes an arbitrary number of arguments and -returns a response. A _route_ is a combination of: - - * A set of parameters to match an incoming request against. - * A handler to process the request and return a response. - -The set of parameters to match against includes static paths, dynamic paths, -path segments, forms, query strings, request format specifiers, and body data. -Rocket uses attributes, which look like function decorators in other languages, -to make declaring routes easy. Routes are declared by annotating a function, the -handler, with the set of parameters to match against. A complete route -declaration looks like this: - -```rust -#[get("/world")] -fn world() -> &'static str { - "Hello, world!" -} -``` - -This declares the `world` route which matches against the static path -`"/world"` for incoming `GET` requests. - - - -Rocket route attributes have the following grammar: - -```ebnf -route := METHOD '(' path, kv_param* ')' - -path := PATH - | 'path' = PATH - -kv_param := 'rank' = INTEGER - | 'form' = STRING - | 'format' = STRING -``` - - - -## Mounting - -Before Rocket dispatches requests to a route, the route needs to be _mounted_ on -an instance of `Rocket`. - -Mounting a route is like namespacing it. Routes are mounted happens via the -`mount` method on a `Rocket` instance. Rocket instances can be created with the -`ignite()` static method. - -The `mount` method takes **1)** a path to namespace a list of routes under, and -**2)** a list of route handlers through the `route!` macro. The `route!` macro -ties Rocket's code generation to your application. To mount the `world` route we -declared above, we would use the following code: - -```rust -rocket::ignite().mount(β€œ/hello”, routes![world]) -``` - -All together, this creates a new `Rocket` instance via the `ignite` function and -mounts the `world` route to the `"/hello"` path. As a result, requests to the -`"/hello/world"` path will be directed to the `world` function. - -## Launching - -Now that Rocket knows about the route, you can tell Rocket to start accepting -requests via the `launch` method. The method starts up the server and waits for -incoming requests. When a request arrives, Rocket finds the matching route and -dispatches the request to the route. - -We typically call `launch` from the `main` function. Our complete _Hello, -world!_ application thus looks like: - -```rust -#![feature(plugin)] -#![plugin(rocket_codegen)] - -extern crate rocket; - -#[get("/world")] -fn world() -> &'static str { - "Hello, world!" -} - -fn main() { - rocket::ignite().mount("/hello", routes![world]).launch(); -} -``` - -Note that we've added the `#![feature(plugin)]` and `#![plugin(rocket_codegen)]` -lines to tell Rust that we'll be using Rocket's code generation plugin. We've -also imported the `rocket` crate into our namespace via `extern crate rocket`. -Finally, we call the `launch` method in the `main` function. - -If we were to run the application above, our console would show: - -```sh -πŸ”§ Configured for development. - => listening: localhost:8000 - => logging: Normal - => session key: false -πŸ›° Mounting '/world': - => GET /hello/world -πŸš€ Rocket has launched from localhost:8000... -``` - -If we now visit `localhost:8000/hello/world`, we would see `Hello, world!`, -exactly as we'd expect. - -By the way, this example's complete crate, ready to `cargo run`, can be found on -[Github](https://github.com/SergioBenitez/Rocket/tree/master/examples/hello_world). -You can find dozens of other complete examples, spanning all of Rocket's -features, in the [Github examples -directory](https://github.com/SergioBenitez/Rocket/tree/master/examples/). - -# Requests - -If all we could do was match against static paths like `"/world"`, Rocket -wouldn't be much fun. Of course, Rocket allows you to match against just about -any information in an incoming request. - -## Dynamic Paths - -You can declare path segments as dynamic by using angle brackets around variable -names in a route's path. For example, if we wanted to say _Hello!_ to anything, -not just the world, we could declare a route and handler like so: - -```rust -#[get("/hello/")] -fn hello(name: &str) -> String { - format!("Hello, {}!", name) -} -``` - -If we were to mount the path at the root (`.mount("/", routes![hello])`), then -any request to a path with two non-empty segments, where the first segment is -`hello`, will be dispatched to the `hello` route. For example, if we were to -visit `/hello/John`, the application would respond with `Hello, John!`. - -You can have any number of dynamic path segments, and the type of the path -segment can be any type that implements the [FromParam -trait](https://api.rocket.rs/rocket/request/trait.FromParam.html), including -your own! Here's a somewhat complicated route to illustrate: - -```rust -#[get("/hello///")] -fn hello(name: &str, age: u8, cool: bool) -> String { - if cool { - format!("You're a cool {} year old, {}!", age, name) - } else { - format!("{}, we need to talk about your coolness.", name) - } -} -``` - -## Forwarding - -What if `cool` ain't a `bool`? Or, what if `age` isn't a `u8`? In this case, the -request is _forwarded_ to the next matching route, if there is any. This -continues until a route doesn't forward the request or there are no more routes -to try. When there are no remaining matching routes, a 404 error, which is -customizable, is returned. - -Routes are tried in increasing _rank_ order. By default, routes with static -paths have a rank of 0 and routes with dynamic paths have a rank of 1. Ranks can -be manually set with the `rank` route parameter. - -To illustrate, consider the following two routes: - -```rust -#[get("/user/")] -fn user(id: usize) -> T { ... } -``` - -```rust -#[get("/user/", rank = 2)] -fn user_str(id: &str) -> T { ... } -``` - -Notice the `rank` parameter in the second route, which sets the rank of the -`user_str` route to 2. If we run this application with both routes mounted at -the root (`.mount("/", routes![user, user_str])`), requests to any route where -the `` path segment is an unsigned integer will be handled by the `user` -route. If the `` path segment is not an unsigned integer, the `user` route -will forward the request. Rocket will then dispatch the request to the next -matching route, `user_str`. - -Forwards can be _caught_ by using a `Result` or `Option` type. For example, if -the type of `id` in the `user` function was `Result`, an `Ok` -variant would indicate that `` was a valid `usize`, while an `Err` would -indicate that `` was not a `usize`. The `Err`'s value would contain the -string that failed to parse as a `usize`. - -By the way, if you were to omit the `rank` parameter in the `user_str` route, -Rocket would emit a warning indicating that the `user` and `user_str` routes -_collide_, or can both match against an incoming request. The `rank` parameter -resolves this collision. - -## Request Guards - -Sometimes we need data associated with a request that isn't a direct input. -Headers and cookies are a good example of this: they simply tag along for the -ride. - -Rocket makes retrieving such information easy: simply add any number of -parameters to the request handler with types that implement the `FromRequest` -trait. If the data can be retrieved from the incoming request, the handler is -called. If it cannot, the handler isn't called, and the request is forwarded on. -In this way, these parameters also act as _guards_: they protect the request -handler from being called erroneously. - -For example, to retrieve cookies and the Content-Type header from a request, we -can declare a route as follows: - -```rust -#[get("/")] -fn index(cookies: &Cookies, content: ContentType) -> String { ... } -``` - -You can implement `FromRequest` for your own types as well. For example, you -might implement `FromRequest` for an `AdminUser` type that validates that the -cookies in the incoming request authenticate an administrator. Then, any handler -with the `AdminUser` type in its argument list is assured that it will only be -invoked if an administrative user is logged in. This centralizes policies, -resulting in a simpler, safer, and more secure application. - -## Data - -At some point, your web application will need to process data, and Rocket makes -it as simple as possible. Data processing, like much of Rocket, is type -directed. To indicate that a handler expects data, annotate a route with a `data -= ""` parameter, where `param` is an argument in the handler of a type -that implement the `FromData` trait. - -### Forms - -Forms are the most common type of data handled in web applications, and Rocket -makes handling them easy. Say your application is processing a form submission -for a new todo `Task`. The form contains two fields: `complete`, a checkbox, and -`description`, a text field. You can easily handle the form request in Rocket -as follows: - -```rust -#[derive(FromForm)] -struct Task { - complete: bool, - description: String, -} - -#[post("/todo", data = "")] -fn new(task: Form) -> String { ... } -``` - -The `Form` type implements the `FromData` trait as long as its generic parameter -implements the `FromForm` trait. In the example, we've derived the `FromForm` -trait automatically for the `Task` structure. If a `POST /todo` request arrives, -the form data will automatically be parsed into the `Task` structure. If the -data that arrives isn't of the correct content-type, the request is forwarded. -If the data is simply invalid, a customizable `400 Bad Request` error is -returned. As before, a forward or failure can be caught by using the `Option` -and `Result` types. - -### Query Strings - -If you change your mind and decide to use query strings instead of `POST` forms -for the todo task, Rocket makes the transition simple: simply declare `` -as a query parameter as follows: - -```rust -#[get("/todo?")] -fn new(task: Task) -> String { ... } -``` - -This works because Rocket uses the `FromForm` trait to parse structures from -query parameters as well. - -### JSON - -Handling JSON data is no harder: simply use the `JSON` type: - -```rust -#[derive(Deserialize)] -struct Task { - description: String, - complete: bool -} - -#[post("/todo", data = "")] -fn new(task: JSON) -> String { ... } -``` - -The only condition is that the generic type to `JSON` implements the -`Deserialize` trait. - -### Streaming Data - -Sometimes you just want to handle the incoming data directly. For example, you -might want to stream the incoming data out to a file. Rocket makes this as -simple as possible: - -```rust -#[post("/upload", format = "text/plain", data = "")] -fn upload(data: Data) -> io::Result> { - data.stream_to_file("/tmp/upload.txt").map(|n| Plain(n.to_string())) -} -``` - -The route above accepts any `POST` request to the `/upload` path with -`Content-Type` `text/plain` The incoming data is streamed out to -`tmp/upload.txt` file, and the number of bytes written is returned as a plain -text response if the upload succeeds. If the upload fails, an error response is -returned. The handler above is complete. It really is that simple! See the -[Github example -code](https://github.com/SergioBenitez/Rocket/blob/master/examples/raw_upload/src/main.rs) -for the full crate. - -# Responses - -Up until the last example, we've been returning the type of `String` from -request handlers. In fact, any type that implements the `Responder` trait can be -returned, including your own! - -## Result - -One of the most common types to return is `Result`. Returning a `Result` means -one of two things: If the error type tself implements `Responder`, the response -will come from either the `Ok` or `Err` value, whichever the variant is. If the -error type does _not_ implement `Responder`, a customizable internal server -error will be returned. - -## JSON - -Responding with JSON data is just as simple: simply return a JSON type. For -example, to respond with the JSON value of the `Task` structure from previous -examples, we would write: - -```rust -#[derive(Serialize)] -struct Task { ... } - -#[get("/todo")] -fn todo() -> JSON { ... } -``` - -Note that the generic type for the JSON response type must implement -`Serialize`. - -## Templates - -Rocket has built-in support for templating. To respond with a rendered template, -simply return a `Template` type: - -```rust -#[get("/")] -fn index() -> Template { - let context = ...; - Template::render("index", &context) -} -``` - -The `render` static method takes in the name of a template (here, `"index"`) and -a value to use as the _context_ for the template's rendering. The context must -contain all of the parameters expected by the template. - -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. - -## Streaming - -When a large amount of data is to be returned, it is often better to stream the -data to the client so as to avoid consuming large amounts of memory. Rocket -provides the `Stream` type to accomplish this. The `Stream` type can be created -from any `Read` type. For example, to stream from a local Unix stream, we might -write: - -```rust -#[get("/stream")] -fn stream() -> io::Result> { - let mut unix = UnixStream::connect("/path/to/my/socket")?; - Stream::from(unix) -} - -``` - -Rocket takes care of the rest. - -# What's next? - -That was just a taste of what Rocket has to offer! There's so much more: - - * [Quickstart](guide/quickstart): How to get started as quickly as possible. - * [Getting Started](guide/getting_started): How to start your first project. - * [Overview](overview): A brief introduction. - * [Guide](guide): A detailed guide and reference to every component. - * [API Documentation](https://api.rocket.rs): The "rustdocs" (API documentation). diff --git a/docs/idea.md b/docs/idea.md deleted file mode 100644 index 6c76b24d..00000000 --- a/docs/idea.md +++ /dev/null @@ -1,194 +0,0 @@ -# Rust Web Framework - -I really want a nice, easy to use, safe, and stupid fast web framework for -Rust. I don't want a monolithic Rails like thing. I'd much rather have -something that looks like Bottle. That is, use decorators to declare routes. - -Nickel.rs looks kinda nice though (see example 2 below - that looks like, but -isn't Nickel). - -Here's what the simplest program might look like with this framework: - -```rust -#[route("/")] -fn home() -> Response { - Response::string("Hello, world!") -} - -fn main() { - RustWebFramework::run("localhost"); -} -``` - -Alternatively... - -```rust -fn home() -> Response { - Response::string("Hello, world!") -} - -fn main() { - route! { - get '/' => home, - } - - RustWebFramework::run("localhost"); -} -``` - -## Arguments - -Here's what a route that takes arguments might look like: - -```rust -#[route("/")] -fn home(page: &str) -> Response { - Response::string(page) -} -``` - -The really neat thing here is that the `route` macro will typecheck the -function signature. The signature should also have a return type of `Response` -(or whatever the response type ends up being) and take a number of equivalent -to those present in the route. The type of the arguments can be any `T` that -implements `From<&str>`. The conversion will be done automatically by the route -handler. As such, the following will work as expected: - -```rust -#[route("/users/")] -fn home(id: isize) -> Response { - let response_string = format!("User ID: {}", id); - Response::string(response_string) -} -``` - -If the conversion fails, the router should 1) print out a debug error message -and return some user-set no-route-exists things, and 2) allow the programmer to -catch the failure if needed. I'm not quite sure what the best way to allow 2) -is at the moment. Here are a couple of ideas: - - 1. Add an `else` parameter to the `route` macro that will take in the name - of a function to call with the raw string (and more) if the routing - fails: - - #[route("/users/", else = home_failed)] - fn home(id: isize) -> Response { ... } - fn home_failed(route: &str) -> Response { ... } - - 2. Allow the parameter type to be `Result`. Then the route is always - called and the user has to check if the conversion was successful or not. - - 3. Pass it off as an error type to another handler. - -Open questions here: - - 1. What syntax should be used to match a path component to a regular - expression? If for some parameter, call it ``, of type `&str`, we - want to constrain matches to the route to `name`s that match some - regular expression, say `[a-z]+`, how do we specify that? Bottle does: - - - - We can probably just do: - - - - -## Methods - -A different HTTP method can be specified with the `method` `route` argument: - -```rust -#[route(method = POST, "/users")] -fn add_user(name: &str, age: isize) -> Response { ... } -``` - -Or, more succinctly: - -```rust -#[POST("/users")] -fn add_user(name: &str, age: isize) -> Response { ... } -``` - -## Route Priority - -Do we allow two routes to possibly match a single path? Can we even determine -that no two paths conflict given regular expressions? Answer: Yes -(http://arstechnica.com/civis/viewtopic.php?f=20&t=472178). And if so, which -route gets priority? An idea is to add a `priority` parameter to the `route` -macro: - -For example: - -```rust -#[GET("/[name: [a-zA-Z]+", priority = 0)] -#[GET("/[name: [a-z]+", priority = 1)] -``` - -The first route allows lower and uppercase letter, while the second route only -allows lowercase letters. In the case that the entire route has lowercase -letters, the route with the higher priority (1, here) gets called, i.e., the -second one. - -## Error Pages - -There's a route for error pages, too: - -```rust -#[route(method = ERROR, status = 404)] -fn page_not_found(...not sure what goes here yet...) -> Response { .. } -``` - -Or, more succinctly: - -```rust -#[error(404)] -fn page_not_found(...not sure what goes here yet...) -> Response { .. } -``` - -## Open Questions - -1. How is HTTP data handled? (IE, interpret `Content-Type`s) - - Form Data - - JSON: Would be nice to automatically convert to structs. - -2. What about Query Params? - -3. How are cookies handled? - - Presumably you would set them via `Response` and get them via...? - -4. Easy support for (but don't bundle it in...) templating would be nice. - Bottle lets you do: - - #[view("template_name")] - fn hello(...) -> HashMap { .. } - - and automatically instantiates the template `template_name` with the - parameters from the HashMap. - -5. Autoreloading. Maybe use the unix-y reloading thing. Maybe not. - -6. Plugins? Would be nice to easily extend routes. - -7. Pre-post hooks/filters? - -8. Caching? - -9. Session support? - - This is basically a server-side local store identified via an ID in a - cookie. - - http://entrproject.org/ - -10. Environment support? (debug vs. production vs. test, etc.) - -11. Model validation? - -12. Internationalization? - -13. Be faster than https://github.com/julienschmidt/httprouter. - -For 2, 3: the obvious solution is to have a `Request` object with that -information. Do we need that, though? Is there something better? diff --git a/docs/outline.md b/docs/outline.md deleted file mode 100644 index 27a7a946..00000000 --- a/docs/outline.md +++ /dev/null @@ -1,83 +0,0 @@ -# This is an evolving outline for the guide. - -**Introduction**: Overarching info about Rocket and the guide. - - * **Foreword** - A bit about the guide. - * **Audience** - Who this guide is intended for. - * **Philosophy** - The ideas behind Rocket. - * **Outline** - An outline of the guide. - -**Quickstart**: Super quick info cloning the repo and running the examples. - -**Getting Started**: Overview of how to use Rocket with Rust. - - * **Rust Nightly** - How to get Rust nightly and why Rocket needs it. - * **Cargo Project** - How to use Rocket in a Cargo project. - * **Project Organization** - Overview of the three crates: lib, codegen, contrib. - * **Running** - Running a Rocket application and what to expect. - * **Configuration** - How to configure Rocket. - * **Rocket.toml** - Syntax and semantics of the Rocket.toml file. - * **Environments** - Explanation and how to set. - * **Logging** - How logging in Rocket works. - -**From Request to Response**: Overview of Rocket's request/response handling. - - * **Routing** - How routing works in Rocket. - * **Request** - How request (pre)processing works. - * **Response** - How response (post) processing works. - -**Routing**: How to route in Rocket. - - * **Overview** - An overview of routes in Rocket. - * **Route Attributes** - Description, explanation, and how to use the attribute. - * **Path** - Explanation of the path argument. - * **Static Parameters** - Static segments in route path. - * **Dynamic Parameters** - Dynamic segments in route path. - * **Segment Parameters** - Segment.. segments in route path. - * **Query Params** - Query parameter in route path. - * **Format** - Explanation of the format attribute. - * **Data** - Exaplanation of the data attribute. - * **FromRequest Arguments** - Parameters derived from the request. - * **Mounting** - Mounting routes at a given path. - * **Collisions and Ranking** - Explains route collisions and ranking. - * **Responses** - Different types of outcomes and their meaning. - * **Complete** - What it means for a request to complete. - * **Forward** - What it means for a request to forward. - * **Catching Errors** - Explanation of catchers and their use. - * **Manual Routing** - How to route without using code generation. - -**Request** - - * **Overview** - An overview of the section. - * **Request Traits** - Explanation of traits used by request handlers. - * **FromParam** - Explanation of the FromParam trait. - * **FromSegments** - Explanation of the FromSegments trait. - * **FromRequest** - Explanation of the FromRequest trait. - * **FromData** - Explanation of the FromParam trait. - * **FromForm** - Explanation of the FromForm trait. - * **FromFormValue** - Explanation of the FromFormValue trait. - * **Data** - How Rocket makes handling streaming data easy. - * **JSON** - Taking in JSON. - * **Forms** - Handling url-encoded forms. Details in next section. - * **Forms** - How Rocket makes forms easy. - * **Custom Validation** - How to add custom validation to forms. - * **Query Params** - How to use/validate query params. - * **Cookies** - Using cookies. - * **Flash** - Using flash cookies. - * **Session** - Using sessions with a private key. - -**Response** - - * **Overview** - An overview of the section. - * **Responder Trait** - Explanation of the Responder trait and its instability. - * **Outcomes** - Different types of responder outcomes. - * **Success** - What it means for a responder to succeed. - * **Failure** - What it means for a responder to fail.k - * **Forward** - What it means for a responder to forward. - * **Simple Responses** - The simple response types Rocket provides. - * Redirect, StatusResponse, Failure, Content - * **NamedFile** - Explanation and use of the NamedFile responder. - * **Stream** - Explanation and use of the Stream response. - * **Flash** - Explanation and use of the Flash response. - * **JSON** - Explanation and use of the JSON responder. - * **Templating** - Templates in contrib.