mirror of https://github.com/rwf2/Rocket.git
Remove stale documents. Merge existing docs into one guide.
This commit is contained in:
parent
0ce41c0f2c
commit
15fe6ec8d0
|
@ -1,18 +1,181 @@
|
||||||
# Overview
|
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).
|
||||||
|
|
||||||
A quick glance at what makes Rocket special.
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# 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
|
# Introduction
|
||||||
|
|
||||||
This overview is a concise introduction to Rocket. There's also a [full,
|
Rocket provides a focused number of core primitives to build web servers and
|
||||||
detailed guide](guide). If you want to get started immediately, see
|
applications with Rust: the rest is up to you. In short, Rocket provides
|
||||||
[quickstart](guide/quickstart) or the [getting started
|
routing, pre-processing of requests, and post-processing of responses. Your
|
||||||
guide](guide/getting_started). Otherwise, welcome!
|
application code fills the gap between pre-processing and post-processing.
|
||||||
|
|
||||||
Rocket makes writing web applications easy, fast, and fun. It is Rocket's goal
|
Rocket _does not_ force decisions on you. Templates, serialization, sessions,
|
||||||
to have you write as little code as necessary to accomplish your goal. In
|
and just about everything else are all pluggable, optional components. While
|
||||||
practice, this means that your code will be free of boilerplate and that the
|
Rocket has official support and libraries for each of these, they are completely
|
||||||
common tasks will be handled for you.
|
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
|
# Routes and Handlers
|
||||||
|
|
||||||
|
@ -41,6 +204,23 @@ fn world() -> &'static str {
|
||||||
This declares the `world` route which matches against the static path
|
This declares the `world` route which matches against the static path
|
||||||
`"/world"` for incoming `GET` requests.
|
`"/world"` for incoming `GET` requests.
|
||||||
|
|
||||||
|
<!--REF-START-->
|
||||||
|
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--REF-END-->
|
||||||
|
|
||||||
## Mounting
|
## Mounting
|
||||||
|
|
||||||
Before Rocket dispatches requests to a route, the route needs to be _mounted_ on
|
Before Rocket dispatches requests to a route, the route needs to be _mounted_ on
|
252
docs/intro.md
252
docs/intro.md
|
@ -1,252 +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.
|
|
||||||
|
|
||||||
# From Request to Response
|
|
||||||
|
|
||||||
This section of the guide provides a grand overview of Rocket by examining a
|
|
||||||
simple application. Let's begin.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#![feature(plugin)]
|
|
||||||
#![plugin(rocket_codegen)]
|
|
||||||
|
|
||||||
extern crate rocket;
|
|
||||||
|
|
||||||
#[get("hi/<name>/<age>")]
|
|
||||||
fn hello(name: &str, age: i8) -> String {
|
|
||||||
format!("Hello, {} year old named {}!", age, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[get("bye/<name>")]
|
|
||||||
fn goodbye(name: &str) -> String {
|
|
||||||
format!("Hello, {} year old named {}!", age, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[error(404)]
|
|
||||||
fn not_found() -> &'static str {
|
|
||||||
"Sorry, I don't know what you're looking for."
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
rocket::ignite()
|
|
||||||
.mount("/", routes![hello, goodbye])
|
|
||||||
.catch(errors![not_found])
|
|
||||||
.launch();
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
# Routing
|
|
||||||
|
|
||||||
The task of a web application is to handle incoming requests by returning an
|
|
||||||
appropriate response. The code that handles the request is called a _request
|
|
||||||
handler_. Requests are made to specific paths, URIs, and with a specific intent,
|
|
||||||
declared via an HTTP method, in mind. The code that determines which request
|
|
||||||
handler should be invoked for a given request is called a _request router_, or
|
|
||||||
just _router_.
|
|
||||||
|
|
||||||
In Rocket, request handlers are regular functions, and you tell Rocket's router
|
|
||||||
which requests are intended for a given handler through an annotation, or
|
|
||||||
attribute, on that function. We call the combination of a handler and its
|
|
||||||
attribute a _route_.
|
|
||||||
|
|
||||||
The code below is one of the simplest routes we can write in Rocket:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#[get("/hello")]
|
|
||||||
fn hello() -> &'static str {
|
|
||||||
"Hello, world!"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
As you might expect, the code declares that the `hello` function is the handler
|
|
||||||
for any `GET` requests to the `/hello` path, and that the response to the
|
|
||||||
request is of type `&'static str` whose value is `Hello, world!`.
|
|
||||||
|
|
||||||
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
|
|
||||||
```
|
|
|
@ -1,245 +0,0 @@
|
||||||
# Overview
|
|
||||||
|
|
||||||
A quick glance at what makes Rocket special.
|
|
||||||
|
|
||||||
# Introduction
|
|
||||||
|
|
||||||
This overview is a concise introduction to Rocket. There's also a [full,
|
|
||||||
detailed guide](guide). If you want to get started immediately, see
|
|
||||||
[quickstart](guide/quickstart) or the [getting started
|
|
||||||
guide](guide/getting_started). Otherwise, welcome!
|
|
||||||
|
|
||||||
Rocket makes writing web applications easy, fast, and fun. Below is a complete
|
|
||||||
Rocket application. In fact, it's [one of many](thisexample) complete, runnable
|
|
||||||
examples in [Rocket's git repository](github). Can you figure out what it does?
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#![feature(plugin)]
|
|
||||||
#![plugin(rocket_codegen)]
|
|
||||||
|
|
||||||
extern crate rocket;
|
|
||||||
|
|
||||||
#[get("/<name>/<age>")]
|
|
||||||
fn hello(name: &str, age: u8) -> String {
|
|
||||||
format!("Hello, {} year old named {}!", age, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
rocket::ignite()
|
|
||||||
.mount("/hello", routes![hello])
|
|
||||||
.launch();
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
If you were to run this application, your console would show:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
🔧 Configured for development.
|
|
||||||
=> listening: localhost:8000
|
|
||||||
=> logging: Normal
|
|
||||||
=> session key: false
|
|
||||||
🛰 Mounting '/hello':
|
|
||||||
=> GET /hello/<name>/<age>
|
|
||||||
🚀 Rocket has launched from localhost:8000...
|
|
||||||
```
|
|
||||||
|
|
||||||
Here's a quick summary of what it does: first, on lines 7 - 10, it declares the
|
|
||||||
`hello` route to `GET /<name>/<age>`, which returns a `String` formatted with
|
|
||||||
`name` and `age` from the dynamic path. Then, in the `main` function, it creates
|
|
||||||
a new `Rocket` instance, mounts the `hello` route at `"/hello"`, and launches
|
|
||||||
the application.
|
|
||||||
|
|
||||||
That's it! Let's break this down.
|
|
||||||
|
|
||||||
We'll start with lines 1 and 2. Rocket depends on the latest version Rust
|
|
||||||
nightly; it makes extensive use of Rust's code generation facilities through
|
|
||||||
compiler plugins. Plugins are still experimental, so we have to tell Rust that
|
|
||||||
we're okay with that by writing `#![feature(plugin)]`. We also have to tell the
|
|
||||||
compiler to use Rocket's code generation crate during compilation with
|
|
||||||
`#![plugin(rocket_codegen)]`. Lines 4 and 5 bring `rocket::Rocket` into the
|
|
||||||
namespace.
|
|
||||||
|
|
||||||
# Routes
|
|
||||||
|
|
||||||
The fun begins on line 7, where the `hello` route and request handler are
|
|
||||||
declared.
|
|
||||||
|
|
||||||
Rocket applications are composed primarily of request handlers and routes. A
|
|
||||||
_request handler_ is 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 request 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, and request format specifiers. Rocket uses
|
|
||||||
Rust attributes, which look like function decorators in other languages, to make
|
|
||||||
declaring routes easy. Routes are declares by annotating a function with the set
|
|
||||||
of parameters to match against. A complete route declaration looks like:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#[get("/index")]
|
|
||||||
fn index() -> &str { "Hello, World!" }
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also use `put`, `post`, `delete`, and `patch` in place of `get`.
|
|
||||||
|
|
||||||
## Dynamic Paths
|
|
||||||
|
|
||||||
The `hello` route declaration beginning on line 7 of our example applications
|
|
||||||
tells Rocket that the `hello` function will handle HTTP `GET` requests to the
|
|
||||||
`<name>/<age>` path. The handler uses `name` and `age` from the path to format
|
|
||||||
and return a `String` to the user. Here are lines 7 - 10 again:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#[get("/<name>/<age>")]
|
|
||||||
fn hello(name: &str, age: u8) -> String {
|
|
||||||
format!("Hello, {} year old named {}!", age, name)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The `<name>` and `<age>` parts of the path are _dynamic_: the actual values for
|
|
||||||
these segments won't be known until someone visits a matching URL. For example,
|
|
||||||
if someone visit `Mike/21`, `<name>` will be `"Mike"`, and `<age>` will be `21`.
|
|
||||||
If someone else visits `Bob/91`, `<name>` and `<age>` will be `"Bob"` and
|
|
||||||
`91`, respectively. Rocket automatically parses dynamic path segments and
|
|
||||||
passes them to the request handler in variables with matching names. This
|
|
||||||
means that `name` and `age` can be used immediately in the handler - no
|
|
||||||
parsing, no checking.
|
|
||||||
|
|
||||||
But wait: what happens if someone goes to a URL with an `<age>` that isn't a
|
|
||||||
valid `u8`? In that case, Rocket doesn't call the handler. Instead, it
|
|
||||||
_forwards_ the request to the next matching route, if any, and ultimately
|
|
||||||
returns a `404` if all of them fail. If you want to know if the user passed in a
|
|
||||||
bad `<age>`, simply use a `Result<u8, &str>` or an `Option<u8>` type for `age`
|
|
||||||
instead. For more details on routing, route collisions, and much more see the
|
|
||||||
[routing](guide/routing) chapter of the guide.
|
|
||||||
|
|
||||||
Oh, one more thing before we move on! Notice how dynamic path parameters can be
|
|
||||||
of different types? Actually, path parameters can be of _any_ type, as long as
|
|
||||||
that type implements Rocket's `FromParam` trait. Rocket uses the `FromParam`
|
|
||||||
implementation to parse and validate the parameter for you automatically. We've
|
|
||||||
implemented `FromParam` for plenty of types in the standard library. See the
|
|
||||||
[FromParam](docs) documentation for more.
|
|
||||||
|
|
||||||
## Mounting
|
|
||||||
|
|
||||||
Now that we understand the `hello` route, let's move on to lines 13 - 14. Before
|
|
||||||
Rocket dispatches requests to a route, the route needs to be _mounted_. And
|
|
||||||
before we can mount a route, we need an instance of `Rocket`.
|
|
||||||
|
|
||||||
Mounting a route is like namespacing it. Routes can be mounted any number of
|
|
||||||
times. Mounting happens with the `mount` method on a `Rocket` instance, which
|
|
||||||
itself is created with the `ignite()` static method. The `mount` method takes a
|
|
||||||
list of route handlers given inside of the `route!` macro. The `route!` macro
|
|
||||||
ties Rocket's code generation to your application. If you'd like to learn more
|
|
||||||
about the `route!` macro, see the [internals guide](guide/internals).
|
|
||||||
|
|
||||||
Let's look at lines 13 - 14 again, which we reproduce below:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
rocket::ignite()
|
|
||||||
.mount(“/hello”, routes![hello])
|
|
||||||
```
|
|
||||||
|
|
||||||
Line 13 creates the new `Rocket` instance, and line 14 mounts the `hello` route
|
|
||||||
at the `"/hello"` path. This makes the `hello` handler available at
|
|
||||||
`/hello/<name>/<age>`. Notice how the mounting path is prepended to the route's
|
|
||||||
path. There's a ton more information about [mounting in the
|
|
||||||
guide](/guides/mounting).
|
|
||||||
|
|
||||||
## Launching
|
|
||||||
|
|
||||||
Now that the route is declared and mounted, the application is ready to launch!
|
|
||||||
To launch an application and have Rocket start listening for and dispatching
|
|
||||||
requests, simply call `launch` on the Rocket instance where routes are mounted.
|
|
||||||
This happens on line 14. Here it is again:
|
|
||||||
|
|
||||||
```
|
|
||||||
rocket.launch()
|
|
||||||
```
|
|
||||||
|
|
||||||
Again, running our full example will show the following in the console:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
🛰 Mounting '/hello':
|
|
||||||
=> GET /hello/<name>/<age>
|
|
||||||
🚀 Rocket has launched from localhost:8000...
|
|
||||||
```
|
|
||||||
|
|
||||||
If you visit `http://localhost:8000/hello/Mike/21`, you'll see "Hello, 21 year
|
|
||||||
old named Mike!". If you have the example running, try visiting other valid and
|
|
||||||
invalid paths and see what happens! This example's complete crate, ready to
|
|
||||||
`cargo run`, can be found at
|
|
||||||
[Github](https://github.com/SergioBenitez/Rocket/tree/master/examples/hello_world).
|
|
||||||
|
|
||||||
# Requests
|
|
||||||
|
|
||||||
There's a lot more we can do with requests. The [requests](guide/requests)
|
|
||||||
chapter of the guide talks about requests in details. We'll give you a short
|
|
||||||
overview of some of the more important and useful features here.
|
|
||||||
|
|
||||||
## Forms and Queries
|
|
||||||
|
|
||||||
Handling forms and query parameters couldn't be easier: declare a form or query
|
|
||||||
parameter in the route attribute and handler, then ensure that its type
|
|
||||||
implements (the automatically derivable) `FromForm`.
|
|
||||||
|
|
||||||
Form parameters are declared by adding `form = "<param_name>"` to the route
|
|
||||||
attribute. 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 {
|
|
||||||
description: String,
|
|
||||||
complete: bool
|
|
||||||
}
|
|
||||||
|
|
||||||
#[post("/todo", form = "<task>")]
|
|
||||||
fn new(task: Task) -> String {
|
|
||||||
...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
If you change your mind and want to use query strings for the form instead,
|
|
||||||
simple declare `<task>` as a query parameter as follows:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#[get("/todo?<task>")]
|
|
||||||
fn new(task: Task) -> String {
|
|
||||||
...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
If the form request is invalid according to the form's type, the handler doesn't
|
|
||||||
get called. Just like in path parameters, you can use `Option` or `Result` in
|
|
||||||
form structure fields to be notified of parsing errors. You can also easily
|
|
||||||
define your own types to validate forms and queries against. For more details,
|
|
||||||
see the [forms](guide/forms) and [queries](guide/queries) chapters of the guide.
|
|
||||||
|
|
||||||
## Guards
|
|
||||||
|
|
||||||
In addition to `FromParam` types, you can include any number of types that
|
|
||||||
implement the `FromRequest` trait in handler arguments. For example, to
|
|
||||||
retrieve cookies from a request, you can use a parameter of `&Cookie` type in a
|
|
||||||
request handler:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#[get("/hello")]
|
|
||||||
fn hello(cookies: &Cookies) -> ..
|
|
||||||
```
|
|
||||||
|
|
||||||
## JSON
|
|
||||||
|
|
||||||
# Responses
|
|
||||||
|
|
||||||
## Responder
|
|
||||||
|
|
||||||
## Templates
|
|
||||||
|
|
||||||
## JSON
|
|
||||||
|
|
||||||
# What's next?
|
|
||||||
|
|
Loading…
Reference in New Issue