1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-10-21 09:23:54 +00:00

Merge pull request #160 from memoryruins/guide

Guide: edits to first half
This commit is contained in:
Nikolay Kim 2018-04-05 19:44:42 -07:00 committed by GitHub
commit 12586db15c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 180 additions and 164 deletions

View file

@ -1,11 +1,8 @@
# Quick start # Quick start
Before you can start writing a actix web applications, youll need a version of Rust installed.
We recommend you use rustup to install or configure such a version.
## Install Rust ## Install Rust
Before we begin, we need to install Rust using the [rustup](https://www.rustup.rs/) installer: Before we begin, we need to install Rust using the [rustup](https://www.rustup.rs/):
```bash ```bash
curl https://sh.rustup.rs -sSf | sh curl https://sh.rustup.rs -sSf | sh
@ -21,9 +18,10 @@ Actix web framework requires rust version 1.21 and up.
## Running Examples ## Running Examples
The fastest way to start experimenting with actix web is to clone the actix web repository The fastest way to start experimenting with actix web is to clone the
and run the included examples in the examples/ directory. The following set of [repository](https://github.com/actix/actix-web) and run the included examples.
commands runs the `basics` example:
The following set of commands runs the `basics` example:
```bash ```bash
git clone https://github.com/actix/actix-web git clone https://github.com/actix/actix-web

View file

@ -1,14 +1,10 @@
# Getting Started # Getting Started
Lets create and run our first actix web application. Well create a new Cargo project Lets write our first actix web application!
that depends on actix web and then run the application.
In the previous section we already installed the required rust version. Now let's create new cargo projects.
## Hello, world! ## Hello, world!
Lets write our first actix web application! Start by creating a new binary-based Start by creating a new binary-based Cargo project and changing into the new directory:
Cargo project and changing into the new directory:
```bash ```bash
cargo new hello-world --bin cargo new hello-world --bin
@ -24,11 +20,12 @@ actix = "0.5"
actix-web = "0.4" actix-web = "0.4"
``` ```
In order to implement a web server, first we need to create a request handler. In order to implement a web server, we first need to create a request handler.
A request handler is a function that accepts an `HttpRequest` instance as its only parameter A request handler is a function that accepts an `HttpRequest` instance as its only parameter
and returns a type that can be converted into `HttpResponse`: and returns a type that can be converted into `HttpResponse`:
Filename: src/main.rs
```rust ```rust
# extern crate actix_web; # extern crate actix_web;
# use actix_web::*; # use actix_web::*;
@ -64,10 +61,10 @@ connections. The server accepts a function that should return an `HttpHandler` i
.run(); .run();
``` ```
That's it. Now, compile and run the program with `cargo run`. That's it! Now, compile and run the program with `cargo run`.
Head over to ``http://localhost:8088/`` to see the results. Head over to ``http://localhost:8088/`` to see the results.
Here is full source of main.rs file: The full source of src/main.rs is listed below:
```rust ```rust
# use std::thread; # use std::thread;
@ -80,7 +77,7 @@ fn index(req: HttpRequest) -> &'static str {
fn main() { fn main() {
# // In the doctest suite we can't run blocking code - deliberately leak a thread # // In the doctest suite we can't run blocking code - deliberately leak a thread
# // If copying this example in show-all mode make sure you skip the thread spawn # // If copying this example in show-all mode, make sure you skip the thread spawn
# // call. # // call.
# thread::spawn(|| { # thread::spawn(|| {
HttpServer::new( HttpServer::new(
@ -92,7 +89,11 @@ fn main() {
} }
``` ```
Note on the `actix` crate. Actix web framework is built on top of actix actor library. > **Note**: actix web is built upon [actix](https://github.com/actix/actix),
> an [actor model](https://en.wikipedia.org/wiki/Actor_model) framework in Rust.
`actix::System` initializes actor system, `HttpServer` is an actor and must run within a `actix::System` initializes actor system, `HttpServer` is an actor and must run within a
properly configured actix system. For more information please check properly configured actix system.
[actix documentation](https://actix.github.io/actix/actix/)
> For more information, check out the [actix documentation](https://actix.github.io/actix/actix/)
> and [actix guide](https://actix.github.io/actix/guide/).

View file

@ -1,20 +1,21 @@
# Application # Application
Actix web provides some primitives to build web servers and applications with Rust. Actix web provides various primitives to build web servers and applications with Rust.
It provides routing, middlewares, pre-processing of requests, and post-processing of responses, It provides routing, middlewares, pre-processing of requests, post-processing of responses,
websocket protocol handling, multipart streams, etc. websocket protocol handling, multipart streams, etc.
All actix web servers are built around the `App` instance. All actix web servers are built around the `App` instance.
It is used for registering routes for resources, and middlewares. It is used for registering routes for resources and middlewares.
It also stores application specific state that is shared across all handlers It also stores application state shared across all handlers within same application.
within same application.
Application acts as a namespace for all routes, i.e all routes for a specific application Applications act as a namespace for all routes, i.e all routes for a specific application
have the same url path prefix. The application prefix always contains a leading "/" slash. have the same url path prefix. The application prefix always contains a leading "/" slash.
If supplied prefix does not contain leading slash, it gets inserted. If a supplied prefix does not contain leading slash, it is automatically inserted.
The prefix should consist of value path segments. i.e for an application with prefix `/app` The prefix should consist of value path segments.
any request with the paths `/app`, `/app/` or `/app/test` would match,
but path `/application` would not match. > For an application with prefix `/app`,
> any request with the paths `/app`, `/app/`, or `/app/test` would match;
> however, the path `/application` would not match.
```rust,ignore ```rust,ignore
# extern crate actix_web; # extern crate actix_web;
@ -31,10 +32,11 @@ but path `/application` would not match.
# } # }
``` ```
In this example application with `/app` prefix and `index.html` resource In this example, an application with the `/app` prefix and a `index.html` resource
gets created. This resource is available as on `/app/index.html` url. are created. This resource is available through the `/app/index.html` url.
For more information check
[*URL Matching*](./qs_5.html#using-a-application-prefix-to-compose-applications) section. > For more information, check the
> [URL Dispatch](./qs_5.html#using-a-application-prefix-to-compose-applications) section.
Multiple applications can be served with one server: Multiple applications can be served with one server:
@ -59,18 +61,17 @@ fn main() {
} }
``` ```
All `/app1` requests route to the first application, `/app2` to the second and then all other to the third. All `/app1` requests route to the first application, `/app2` to the second, and all other to the third.
Applications get matched based on registration order, if an application with more general **Applications get matched based on registration order**. If an application with a more generic
prefix is registered before a less generic one, that would effectively block the less generic prefix is registered before a less generic one, it would effectively block the less generic
application from getting matched. For example, if *application* with prefix "/" gets registered application matching. For example, if an `App` with the prefix `"/"` was registered
as first application, it would match all incoming requests. as the first application, it would match all incoming requests.
## State ## State
Application state is shared with all routes and resources within the same application. Application state is shared with all routes and resources within the same application.
State can be accessed with the `HttpRequest::state()` method as a read-only, When using an http actor,state can be accessed with the `HttpRequest::state()` as read-only,
but an interior mutability pattern with `RefCell` can be used to achieve state mutability. but interior mutability with `RefCell` can be used to achieve state mutability.
State can be accessed with `HttpContext::state()` when using an http actor.
State is also available for route matching predicates and middlewares. State is also available for route matching predicates and middlewares.
Let's write a simple application that uses shared state. We are going to store request count Let's write a simple application that uses shared state. We are going to store request count
@ -102,8 +103,8 @@ fn main() {
} }
``` ```
Note on application state, http server accepts an application factory rather than an application > **Note**: http server accepts an application factory rather than an application
instance. Http server constructs an application instance for each thread, so application state > instance. Http server constructs an application instance for each thread, thus application state
must be constructed multiple times. If you want to share state between different threads, a > must be constructed multiple times. If you want to share state between different threads, a
shared object should be used, like `Arc`. Application state does not need to be `Send` and `Sync` > shared object should be used, e.g. `Arc`. Application state does not need to be `Send` and `Sync`,
but the application factory must be `Send` + `Sync`. > but the application factory must be `Send` + `Sync`.

View file

@ -1,13 +1,19 @@
# Server # Server
The [*HttpServer*](../actix_web/struct.HttpServer.html) type is responsible for The [**HttpServer**](../actix_web/struct.HttpServer.html) type is responsible for
serving http requests. *HttpServer* accepts application factory as a parameter, serving http requests.
Application factory must have `Send` + `Sync` boundaries. More about that in the
*multi-threading* section. To bind to a specific socket address, `bind()` must be used. `HttpServer` accepts an application factory as a parameter, and the
This method can be called multiple times. To start the http server, one of the *start* application factory must have `Send` + `Sync` boundaries. More about that in the
methods can be used. `start()` method starts a simple server, `start_tls()` or `start_ssl()` *multi-threading* section.
starts ssl server. *HttpServer* is an actix actor, it has to be initialized
within a properly configured actix system: To bind to a specific socket address, `bind()` must be used, and it may be called multiple times.
To start the http server, one of the start methods.
- use `start()` for a simple server
- use `start_tls()` or `start_ssl()` for a ssl server
`HttpServer` is an actix actor. It must be initialized within a properly configured actix system:
```rust ```rust
# extern crate actix; # extern crate actix;
@ -29,17 +35,17 @@ fn main() {
} }
``` ```
It is possible to start a server in a separate thread with the *spawn()* method. In that > It is possible to start a server in a separate thread with the `spawn()` method. In that
case the server spawns a new thread and creates a new actix system in it. To stop > case the server spawns a new thread and creates a new actix system in it. To stop
this server, send a `StopServer` message. > this server, send a `StopServer` message.
Http server is implemented as an actix actor. It is possible to communicate with the server `HttpServer` is implemented as an actix actor. It is possible to communicate with the server
via a messaging system. All start methods like `start()`, `start_ssl()`, etc. return the via a messaging system. All start methods, e.g. `start()` and `start_ssl()`, return the
address of the started http server. Actix http server accepts several messages: address of the started http server. It accepts several messages:
* `PauseServer` - Pause accepting incoming connections - `PauseServer` - Pause accepting incoming connections
* `ResumeServer` - Resume accepting incoming connections - `ResumeServer` - Resume accepting incoming connections
* `StopServer` - Stop incoming connection processing, stop all workers and exit - `StopServer` - Stop incoming connection processing, stop all workers and exit
```rust ```rust
# extern crate futures; # extern crate futures;
@ -74,7 +80,7 @@ fn main() {
## Multi-threading ## Multi-threading
Http server automatically starts an number of http workers, by default `HttpServer` automatically starts an number of http workers, by default
this number is equal to number of logical CPUs in the system. This number this number is equal to number of logical CPUs in the system. This number
can be overridden with the `HttpServer::threads()` method. can be overridden with the `HttpServer::threads()` method.
@ -92,8 +98,10 @@ fn main() {
``` ```
The server creates a separate application instance for each created worker. Application state The server creates a separate application instance for each created worker. Application state
is not shared between threads, to share state `Arc` could be used. Application state is not shared between threads. To share state, `Arc` could be used.
does not need to be `Send` and `Sync` but application factory must be `Send` + `Sync`.
> Application state does not need to be `Send` and `Sync`,
> but factories must be `Send` + `Sync`.
## SSL ## SSL
@ -123,22 +131,21 @@ fn main() {
} }
``` ```
Note on *HTTP/2.0* protocol over tls without prior knowledge, it requires > **Note**: the *HTTP/2.0* protocol requires
[tls alpn](https://tools.ietf.org/html/rfc7301). At the moment only > [tls alpn](https://tools.ietf.org/html/rfc7301).
`openssl` has `alpn ` support. > At the moment, only `openssl` has `alpn` support.
> For a full example, check out
Please check [example](https://github.com/actix/actix-web/tree/master/examples/tls) > [examples/tls](https://github.com/actix/actix-web/tree/master/examples/tls).
for a full example.
## Keep-Alive ## Keep-Alive
Actix can wait for requests on a keep-alive connection. *Keep alive* Actix can wait for requests on a keep-alive connection.
connection behavior is defined by server settings.
* `75` or `Some(75)` or `KeepAlive::Timeout(75)` - enable 75 sec *keep alive* timer according > *keep alive* connection behavior is defined by server settings.
request and response settings.
* `None` or `KeepAlive::Disabled` - disable *keep alive*. - `75`, `Some(75)`, `KeepAlive::Timeout(75)` - enable 75 second *keep alive* timer.
* `KeepAlive::Tcp(75)` - Use `SO_KEEPALIVE` socket option. - `None` or `KeepAlive::Disabled` - disable *keep alive*.
- `KeepAlive::Tcp(75)` - use `SO_KEEPALIVE` socket option.
```rust ```rust
# extern crate actix_web; # extern crate actix_web;
@ -163,11 +170,12 @@ fn main() {
} }
``` ```
If first option is selected then *keep alive* state is If the first option is selected, then *keep alive* state is
calculated based on the response's *connection-type*. By default calculated based on the response's *connection-type*. By default
`HttpResponse::connection_type` is not defined in that case *keep alive* `HttpResponse::connection_type` is not defined. In that case *keep alive* is
defined by request's http version. Keep alive is off for *HTTP/1.0* defined by the request's http version.
and is on for *HTTP/1.1* and *HTTP/2.0*.
> *keep alive* is **off** for *HTTP/1.0* and is **on** for *HTTP/1.1* and *HTTP/2.0*.
*Connection type* can be change with `HttpResponseBuilder::connection_type()` method. *Connection type* can be change with `HttpResponseBuilder::connection_type()` method.
@ -186,19 +194,19 @@ fn index(req: HttpRequest) -> HttpResponse {
## Graceful shutdown ## Graceful shutdown
Actix http server supports graceful shutdown. After receiving a stop signal, workers `HttpServer` supports graceful shutdown. After receiving a stop signal, workers
have a specific amount of time to finish serving requests. Workers still alive after the have a specific amount of time to finish serving requests. Any workers still alive after the
timeout are force-dropped. By default the shutdown timeout is set to 30 seconds. timeout are force-dropped. By default the shutdown timeout is set to 30 seconds.
You can change this parameter with the `HttpServer::shutdown_timeout()` method. You can change this parameter with the `HttpServer::shutdown_timeout()` method.
You can send a stop message to the server with the server address and specify if you want You can send a stop message to the server with the server address and specify if you want
graceful shutdown or not. The `start()` methods return address of the server. graceful shutdown or not. The `start()` methods returns address of the server.
Http server handles several OS signals. *CTRL-C* is available on all OSs, `HttpServer` handles several OS signals. *CTRL-C* is available on all OSs,
other signals are available on unix systems. other signals are available on unix systems.
* *SIGINT* - Force shutdown workers - *SIGINT* - Force shutdown workers
* *SIGTERM* - Graceful shutdown workers - *SIGTERM* - Graceful shutdown workers
* *SIGQUIT* - Force shutdown workers - *SIGQUIT* - Force shutdown workers
It is possible to disable signal handling with `HttpServer::disable_signals()` method. > It is possible to disable signal handling with `HttpServer::disable_signals()` method.

View file

@ -1,17 +1,18 @@
# Handler # Handler
A request handler can be any object that implements A request handler can be any object that implements
[*Handler trait*](../actix_web/dev/trait.Handler.html). [`Handler` trait](../actix_web/dev/trait.Handler.html).
Request handling happens in two stages. First the handler object is called.
Handler can return any object that implements Request handling happens in two stages. First the handler object is called,
[*Responder trait*](../actix_web/trait.Responder.html#foreign-impls). returning any object that implements the
Then `respond_to()` is called on the returned object. And finally [`Responder` trait](../actix_web/trait.Responder.html#foreign-impls).
result of the `respond_to()` call is converted to a `Reply` object. Then, `respond_to()` is called on the returned object, converting itself to a `Reply` or `Error`.
By default actix provides `Responder` implementations for some standard types, By default actix provides `Responder` implementations for some standard types,
like `&'static str`, `String`, etc. such as `&'static str`, `String`, etc.
For a complete list of implementations, check
[*Responder documentation*](../actix_web/trait.Responder.html#foreign-impls). > For a complete list of implementations, check
> [*Responder documentation*](../actix_web/trait.Responder.html#foreign-impls).
Examples of valid handlers: Examples of valid handlers:
@ -39,15 +40,16 @@ fn index(req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> {
} }
``` ```
Some notes on shared application state and handler state. If you noticed *Handler* trait is generic over *S*, which defines the application state's type.
*Handler* trait is generic over *S*, which defines application state type. So Application state is accessible from the handler with the `HttpRequest::state()` method;
application state is accessible from handler with the `HttpRequest::state()` method. however, state is accessible as a read-only reference. If you need mutable access to state,
But state is accessible as a read-only reference - if you need mutable access to state it must be implemented.
you have to implement it yourself. On other hand, handler can mutably access its own state
as the `handle` method takes a mutable reference to *self*. Beware, actix creates multiple copies > **Note**: Alternatively, the handler can mutably access its own state because the `handle` method takes
of application state and handlers, unique for each thread, so if you run your > mutable reference to *self*. **Beware**, actix creates multiple copies
application in several threads, actix will create the same amount as number of threads > of the application state and the handlers, unique for each thread. If you run your
of application state objects and handler objects. > application in several threads, actix will create the same amount as number of threads
> of application state objects and handler objects.
Here is an example of a handler that stores the number of processed requests: Here is an example of a handler that stores the number of processed requests:
@ -69,8 +71,8 @@ impl<S> Handler<S> for MyHandler {
# fn main() {} # fn main() {}
``` ```
This handler will work, but `self.0` will be different depending on the number of threads and Although this handler will work, `self.0` will be different depending on the number of threads and
number of requests processed per thread. A proper implementation would use `Arc` and `AtomicUsize` number of requests processed per thread. A proper implementation would use `Arc` and `AtomicUsize`.
```rust ```rust
# extern crate actix; # extern crate actix;
@ -111,14 +113,15 @@ fn main() {
} }
``` ```
Be careful with synchronization primitives like *Mutex* or *RwLock*. Actix web framework > Be careful with synchronization primitives like `Mutex` or `RwLock`. Actix web framework
handles requests asynchronously; by blocking thread execution all concurrent > handles requests asynchronously. By blocking thread execution, all concurrent
request handling processes would block. If you need to share or update some state > request handling processes would block. If you need to share or update some state
from multiple threads consider using the [actix](https://actix.github.io/actix/actix/) actor system. > from multiple threads, consider using the [actix](https://actix.github.io/actix/actix/) actor system.
## Response with custom type ## Response with custom type
To return a custom type directly from a handler function, the type needs to implement the `Responder` trait. To return a custom type directly from a handler function, the type needs to implement the `Responder` trait.
Let's create a response for a custom type that serializes to an `application/json` response: Let's create a response for a custom type that serializes to an `application/json` response:
```rust ```rust
@ -171,10 +174,10 @@ fn main() {
## Async handlers ## Async handlers
There are two different types of async handlers. There are two different types of async handlers. Response objects can be generated asynchronously
or more precisely, any type that implements the [*Responder*](../actix_web/trait.Responder.html) trait.
Response objects can be generated asynchronously or more precisely, any type In this case, the handler must return a `Future` object that resolves to the *Responder* type, i.e:
that implements the [*Responder*](../actix_web/trait.Responder.html) trait. In this case the handler must return a `Future` object that resolves to the *Responder* type, i.e:
```rust ```rust
# extern crate actix_web; # extern crate actix_web;
@ -205,8 +208,8 @@ fn main() {
} }
``` ```
Or the response body can be generated asynchronously. In this case body Or the response body can be generated asynchronously. In this case, body
must implement stream trait `Stream<Item=Bytes, Error=Error>`, i.e: must implement the stream trait `Stream<Item=Bytes, Error=Error>`, i.e:
```rust ```rust
# extern crate actix_web; # extern crate actix_web;
@ -233,7 +236,7 @@ fn main() {
Both methods can be combined. (i.e Async response with streaming body) Both methods can be combined. (i.e Async response with streaming body)
It is possible to return a `Result` where the `Result::Item` type can be `Future`. It is possible to return a `Result` where the `Result::Item` type can be `Future`.
In this example the `index` handler can return an error immediately or return a In this example, the `index` handler can return an error immediately or return a
future that resolves to a `HttpResponse`. future that resolves to a `HttpResponse`.
```rust ```rust
@ -265,11 +268,11 @@ fn index(req: HttpRequest) -> Result<Box<Future<Item=HttpResponse, Error=Error>>
## Different return types (Either) ## Different return types (Either)
Sometimes you need to return different types of responses. For example Sometimes, you need to return different types of responses. For example,
you can do error check and return error and return async response otherwise. you can error check and return errors, return async responses, or any result that requires two different types.
Or any result that requires two different types.
For this case the [*Either*](../actix_web/enum.Either.html) type can be used. For this case, the [`Either`](../actix_web/enum.Either.html) type can be used.
*Either* allows combining two different responder types into a single type. `Either` allows combining two different responder types into a single type.
```rust ```rust
# extern crate actix_web; # extern crate actix_web;

View file

@ -1,10 +1,11 @@
# Errors # Errors
Actix uses [`Error` type](../actix_web/error/struct.Error.html) Actix uses the [`Error` type](../actix_web/error/struct.Error.html)
and [`ResponseError` trait](../actix_web/error/trait.ResponseError.html) and [`ResponseError` trait](../actix_web/error/trait.ResponseError.html)
for handling handler's errors. for handling handler's errors.
Any error that implements the `ResponseError` trait can be returned as an error value. Any error that implements the `ResponseError` trait can be returned as an error value.
*Handler* can return an *Result* object; actix by default provides `Handler` can return an `Result` object. By default, actix provides a
`Responder` implementation for compatible result types. Here is the implementation `Responder` implementation for compatible result types. Here is the implementation
definition: definition:
@ -12,7 +13,8 @@ definition:
impl<T: Responder, E: Into<Error>> Responder for Result<T, E> impl<T: Responder, E: Into<Error>> Responder for Result<T, E>
``` ```
And any error that implements `ResponseError` can be converted into an `Error` object. Any error that implements `ResponseError` can be converted into an `Error` object.
For example, if the *handler* function returns `io::Error`, it would be converted For example, if the *handler* function returns `io::Error`, it would be converted
into an `HttpInternalServerError` response. Implementation for `io::Error` is provided into an `HttpInternalServerError` response. Implementation for `io::Error` is provided
by default. by default.
@ -35,7 +37,7 @@ fn index(req: HttpRequest) -> io::Result<fs::NamedFile> {
## Custom error response ## Custom error response
To add support for custom errors, all we need to do is just implement the `ResponseError` trait To add support for custom errors, all we need to do is implement the `ResponseError` trait
for the custom error type. The `ResponseError` trait has a default implementation for the custom error type. The `ResponseError` trait has a default implementation
for the `error_response()` method: it generates a *500* response. for the `error_response()` method: it generates a *500* response.
@ -109,7 +111,7 @@ fn index(req: HttpRequest) -> Result<&'static str, MyError> {
## Error helpers ## Error helpers
Actix provides a set of error helper types. It is possible to use them for generating Actix provides a set of error helper types. It is possible to use them for generating
specific error responses. We can use helper types for the first example with custom error. specific error responses. We can use the helper types for the first example with a custom error.
```rust ```rust
# extern crate actix_web; # extern crate actix_web;

View file

@ -2,17 +2,19 @@
URL dispatch provides a simple way for mapping URLs to `Handler` code using a simple pattern URL dispatch provides a simple way for mapping URLs to `Handler` code using a simple pattern
matching language. If one of the patterns matches the path information associated with a request, matching language. If one of the patterns matches the path information associated with a request,
a particular handler object is invoked. A handler is a specific object that implements the a particular handler object is invoked.
`Handler` trait, defined in your application, that receives the request and returns
a response object. More information is available in the [handler section](../qs_4.html). > A handler is a specific object that implements the
> `Handler` trait, defined in your application, that receives the request and returns
> a response object. More information is available in the [handler section](../qs_4.html).
## Resource configuration ## Resource configuration
Resource configuration is the act of adding a new resources to an application. Resource configuration is the act of adding a new resources to an application.
A resource has a name, which acts as an identifier to be used for URL generation. A resource has a name, which acts as an identifier to be used for URL generation.
The name also allows developers to add routes to existing resources. The name also allows developers to add routes to existing resources.
A resource also has a pattern, meant to match against the *PATH* portion of a *URL*, A resource also has a pattern, meant to match against the *PATH* portion of a *URL*.
it does not match against the *QUERY* portion (the portion following the scheme and It does not match against the *QUERY* portion (the portion following the scheme and
port, e.g., */foo/bar* in the *URL* *http://localhost:8080/foo/bar?q=value*). port, e.g., */foo/bar* in the *URL* *http://localhost:8080/foo/bar?q=value*).
The [App::resource](../actix_web/struct.App.html#method.resource) methods The [App::resource](../actix_web/struct.App.html#method.resource) methods
@ -43,7 +45,7 @@ The *Configuration function* has the following type:
``` ```
The *Configuration function* can set a name and register specific routes. The *Configuration function* can set a name and register specific routes.
If a resource does not contain any route or does not have any matching routes it If a resource does not contain any route or does not have any matching routes, it
returns *NOT FOUND* http response. returns *NOT FOUND* http response.
## Configuring a Route ## Configuring a Route
@ -55,8 +57,9 @@ all requests and the default handler is `HttpNotFound`.
The application routes incoming requests based on route criteria which are defined during The application routes incoming requests based on route criteria which are defined during
resource registration and route registration. Resource matches all routes it contains in resource registration and route registration. Resource matches all routes it contains in
the order the routes were registered via `Resource::route()`. A *Route* can contain the order the routes were registered via `Resource::route()`.
any number of *predicates* but only one handler.
> A *Route* can contain any number of *predicates* but only one handler.
```rust ```rust
# extern crate actix_web; # extern crate actix_web;
@ -74,10 +77,11 @@ fn main() {
} }
``` ```
In this example `HttpResponse::Ok()` is returned for *GET* requests, In this example, `HttpResponse::Ok()` is returned for *GET* requests.
if request contains `Content-Type` header and value of this header is *text/plain* If a request contains `Content-Type` header, the value of this header is *text/plain*,
and path equals to `/path`. Resource calls handle of the first matching route. and path equals to `/path`, Resource calls handle of the first matching route.
If a resource can not match any route a "NOT FOUND" response is returned.
If a resource can not match any route, a "NOT FOUND" response is returned.
[*Resource::route()*](../actix_web/struct.Resource.html#method.route) returns a [*Resource::route()*](../actix_web/struct.Resource.html#method.route) returns a
[*Route*](../actix_web/struct.Route.html) object. Route can be configured with a [*Route*](../actix_web/struct.Route.html) object. Route can be configured with a
@ -118,9 +122,7 @@ arguments provided to a route configuration returns `false` during a check, that
skipped and route matching continues through the ordered set of routes. skipped and route matching continues through the ordered set of routes.
If any route matches, the route matching process stops and the handler associated with If any route matches, the route matching process stops and the handler associated with
the route is invoked. the route is invoked. If no route matches after all route patterns are exhausted, a *NOT FOUND* response get returned.
If no route matches after all route patterns are exhausted, a *NOT FOUND* response get returned.
## Resource pattern syntax ## Resource pattern syntax
@ -208,8 +210,9 @@ For example, for the URL */abc/*:
* */abc/{foo}* will not match. * */abc/{foo}* will not match.
* */{foo}/* will match. * */{foo}/* will match.
Note that path will be URL-unquoted and decoded into valid unicode string before > **Note**: path will be URL-unquoted and decoded into valid unicode string before
matching pattern and values representing matched path segments will be URL-unquoted too. > matching pattern and values representing matched path segments will be URL-unquoted too.
So for instance, the following pattern: So for instance, the following pattern:
``` ```
@ -292,11 +295,11 @@ any) is skipped.
For security purposes, if a segment meets any of the following conditions, For security purposes, if a segment meets any of the following conditions,
an `Err` is returned indicating the condition met: an `Err` is returned indicating the condition met:
* Decoded segment starts with any of: `.` (except `..`), `*` * Decoded segment starts with any of: `.` (except `..`), `*`
* Decoded segment ends with any of: `:`, `>`, `<` * Decoded segment ends with any of: `:`, `>`, `<`
* Decoded segment contains any of: `/` * Decoded segment contains any of: `/`
* On Windows, decoded segment contains any of: '\' * On Windows, decoded segment contains any of: '\'
* Percent-encoding results in invalid UTF8. * Percent-encoding results in invalid UTF8.
As a result of these conditions, a `PathBuf` parsed from request path parameter is As a result of these conditions, a `PathBuf` parsed from request path parameter is
safe to interpolate within, or use as a suffix of, a path without additional checks. safe to interpolate within, or use as a suffix of, a path without additional checks.
@ -350,8 +353,8 @@ fn main() {
} }
``` ```
It also possible to extract path information to a tuple, in this case you don't need It also possible to extract path information to a tuple. In this case, you don't need
to define extra type, just use tuple for as a `Path` generic type. to define an extra type; use a tuple as a `Path` generic type.
Here is previous example re-written using tuple instead of specific type. Here is previous example re-written using tuple instead of specific type.
@ -433,21 +436,21 @@ fn main() {
By normalizing it means: By normalizing it means:
- Add a trailing slash to the path. * Add a trailing slash to the path.
- Double slashes are replaced by one. * Double slashes are replaced by one.
The handler returns as soon as it finds a path that resolves The handler returns as soon as it finds a path that resolves
correctly. The order if all enable is 1) merge, 3) both merge and append correctly. The order if all enable is 1) merge, 3) both merge and append
and 3) append. If the path resolves with and 3) append. If the path resolves with
at least one of those conditions, it will redirect to the new path. at least one of those conditions, it will redirect to the new path.
If *append* is *true* append slash when needed. If a resource is If *append* is *true*, append slash when needed. If a resource is
defined with trailing slash and the request doesn't have one, it will defined with trailing slash and the request doesn't have one, it will
be appended automatically. be appended automatically.
If *merge* is *true*, merge multiple consecutive slashes in the path into one. If *merge* is *true*, merge multiple consecutive slashes in the path into one.
This handler designed to be use as a handler for application's *default resource*. This handler designed to be used as a handler for application's *default resource*.
```rust ```rust
# extern crate actix_web; # extern crate actix_web;
@ -468,7 +471,7 @@ fn main() {
In this example `/resource`, `//resource///` will be redirected to `/resource/`. In this example `/resource`, `//resource///` will be redirected to `/resource/`.
In this example path normalization handler is registered for all methods, In this example, the path normalization handler is registered for all methods,
but you should not rely on this mechanism to redirect *POST* requests. The redirect of the but you should not rely on this mechanism to redirect *POST* requests. The redirect of the
slash-appending *Not Found* will turn a *POST* request into a GET, losing any slash-appending *Not Found* will turn a *POST* request into a GET, losing any
*POST* data in the original request. *POST* data in the original request.
@ -493,7 +496,7 @@ fn main() {
## Using an Application Prefix to Compose Applications ## Using an Application Prefix to Compose Applications
The `App::prefix()`" method allows to set a specific application prefix. The `App::prefix()` method allows to set a specific application prefix.
This prefix represents a resource prefix that will be prepended to all resource patterns added This prefix represents a resource prefix that will be prepended to all resource patterns added
by the resource configuration. This can be used to help mount a set of routes at a different by the resource configuration. This can be used to help mount a set of routes at a different
location than the included callable's author intended while still maintaining the same location than the included callable's author intended while still maintaining the same
@ -556,7 +559,7 @@ fn main() {
} }
``` ```
In this example *index* handler will be called only if request contains *CONTENT-TYPE* header. In this example, *index* handler will be called only if request contains *CONTENT-TYPE* header.
Predicates have access to the application's state via `HttpRequest::state()`. Predicates have access to the application's state via `HttpRequest::state()`.
Also predicates can store extra information in Also predicates can store extra information in
@ -565,7 +568,7 @@ Also predicates can store extra information in
### Modifying predicate values ### Modifying predicate values
You can invert the meaning of any predicate value by wrapping it in a `Not` predicate. You can invert the meaning of any predicate value by wrapping it in a `Not` predicate.
For example if you want to return "METHOD NOT ALLOWED" response for all methods For example, if you want to return "METHOD NOT ALLOWED" response for all methods
except "GET": except "GET":
```rust ```rust