2017-04-17 02:48:59 +00:00
|
|
|
|
###############################################################################
|
|
|
|
|
# Steps to "How Rocket Works"
|
|
|
|
|
###############################################################################
|
|
|
|
|
|
|
|
|
|
[[steps]]
|
|
|
|
|
name = "Validation"
|
|
|
|
|
color = "blue"
|
|
|
|
|
content = '''
|
|
|
|
|
First, Rocket validates a matching request by ensuring that all of the types in
|
|
|
|
|
a given handler can be derived from the incoming request. If the types cannot be
|
|
|
|
|
derived, the request is forwarded to the next matching route until a route’s
|
|
|
|
|
types validate or there are no more routes to try. If all routes fail, a
|
|
|
|
|
customizable **404** error is returned.
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
#[post("/user", data = "<new_user>")]
|
|
|
|
|
fn new_user(admin: AdminUser, new_user: Form<User>) -> T {
|
2021-09-14 03:48:47 +00:00
|
|
|
|
...
|
2017-04-17 02:48:59 +00:00
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
For the `new_user` handler above to be called, the following conditions must
|
|
|
|
|
hold:
|
|
|
|
|
|
2018-10-22 21:47:35 +00:00
|
|
|
|
* The request method must be `POST`.
|
|
|
|
|
* The request path must be `/user`.
|
|
|
|
|
* The request must contain `data` in its body.
|
|
|
|
|
* The request metadata must authenticate an `AdminUser`.
|
|
|
|
|
* The request body must be a form that parses into a `User` struct.
|
2017-04-17 02:48:59 +00:00
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
[[steps]]
|
|
|
|
|
name = "Processing"
|
|
|
|
|
color = "purple"
|
|
|
|
|
content = '''
|
|
|
|
|
Next, the request is processed by an arbitrary handler. This is where most of
|
|
|
|
|
the business logic in an application resides, and the part of your applications
|
|
|
|
|
you’ll likely spend the most time writing. In Rocket, handlers are simply
|
|
|
|
|
functions - that’s it! The only caveat is that the function’s return type must
|
|
|
|
|
implement the `Responder` trait. The `new_user` function above is an example of
|
|
|
|
|
a handler.
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
[[steps]]
|
|
|
|
|
name = "Response"
|
|
|
|
|
color = "red"
|
|
|
|
|
content = '''
|
|
|
|
|
Finally, Rocket responds to the client by transforming the return value of the
|
|
|
|
|
handler into an HTTP response. The HTTP response generated from the returned
|
|
|
|
|
value depends on the type’s specific `Responder` trait implementation.
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
fn route() -> T { ... }
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
If the function above is used as a handler, for instance, then the type `T` must
|
|
|
|
|
implement `Responder`. Rocket provides many useful responder types out of the
|
|
|
|
|
box. They include:
|
|
|
|
|
|
2018-10-22 21:47:35 +00:00
|
|
|
|
* `Json<T>`: Serializes the structure T into JSON and returns it to
|
|
|
|
|
the client.
|
|
|
|
|
* `Template`: Renders a template file and returns it to the client.
|
|
|
|
|
* `Redirect`: Returns a properly formatted HTTP redirect.
|
|
|
|
|
* `NamedFile`: Streams a given file to the client with the
|
|
|
|
|
Content-Type taken from the file’s extension.
|
|
|
|
|
* `Stream`: Streams data to the client from an arbitrary `Read` value.
|
|
|
|
|
* Many Primitive Types: `String`, `&str`, `File`, `Option`, `Result`, and
|
|
|
|
|
others all implement the `Responder` trait.
|
2017-04-17 02:48:59 +00:00
|
|
|
|
'''
|