Remove stale documents. Merge existing docs into one guide.

This commit is contained in:
Sergio Benitez 2016-11-13 19:01:09 -08:00
parent 0ce41c0f2c
commit 15fe6ec8d0
3 changed files with 190 additions and 507 deletions

View File

@ -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
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 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 makes writing web applications easy, fast, and fun. It is Rocket's goal
to have you write as little code as necessary to accomplish your goal. In
practice, this means that your code will be free of boilerplate and that the
common tasks will be handled for you.
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
@ -41,6 +204,23 @@ fn world() -> &'static str {
This declares the `world` route which matches against the static path
`"/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
Before Rocket dispatches requests to a route, the route needs to be _mounted_ on

View File

@ -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
```

View File

@ -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?