mirror of
https://github.com/actix/actix-extras.git
synced 2024-11-30 18:34:36 +01:00
Merge pull request #160 from memoryruins/guide
Guide: edits to first half
This commit is contained in:
commit
12586db15c
@ -1,11 +1,8 @@
|
||||
# Quick start
|
||||
|
||||
Before you can start writing a actix web applications, you’ll need a version of Rust installed.
|
||||
We recommend you use rustup to install or configure such a version.
|
||||
|
||||
## 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
|
||||
curl https://sh.rustup.rs -sSf | sh
|
||||
@ -21,9 +18,10 @@ Actix web framework requires rust version 1.21 and up.
|
||||
|
||||
## Running Examples
|
||||
|
||||
The fastest way to start experimenting with actix web is to clone the actix web repository
|
||||
and run the included examples in the examples/ directory. The following set of
|
||||
commands runs the `basics` example:
|
||||
The fastest way to start experimenting with actix web is to clone the
|
||||
[repository](https://github.com/actix/actix-web) and run the included examples.
|
||||
|
||||
The following set of commands runs the `basics` example:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/actix/actix-web
|
||||
|
@ -1,14 +1,10 @@
|
||||
# Getting Started
|
||||
|
||||
Let’s create and run our first actix web application. We’ll create a new Cargo project
|
||||
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.
|
||||
Let’s write our first actix web application!
|
||||
|
||||
## Hello, world!
|
||||
|
||||
Let’s write our first actix web application! Start by creating a new binary-based
|
||||
Cargo project and changing into the new directory:
|
||||
Start by creating a new binary-based Cargo project and changing into the new directory:
|
||||
|
||||
```bash
|
||||
cargo new hello-world --bin
|
||||
@ -24,11 +20,12 @@ actix = "0.5"
|
||||
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
|
||||
and returns a type that can be converted into `HttpResponse`:
|
||||
|
||||
Filename: src/main.rs
|
||||
```rust
|
||||
# extern crate actix_web;
|
||||
# use actix_web::*;
|
||||
@ -64,10 +61,10 @@ connections. The server accepts a function that should return an `HttpHandler` i
|
||||
.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.
|
||||
|
||||
Here is full source of main.rs file:
|
||||
The full source of src/main.rs is listed below:
|
||||
|
||||
```rust
|
||||
# use std::thread;
|
||||
@ -80,7 +77,7 @@ fn index(req: HttpRequest) -> &'static str {
|
||||
|
||||
fn main() {
|
||||
# // 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.
|
||||
# thread::spawn(|| {
|
||||
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
|
||||
properly configured actix system. For more information please check
|
||||
[actix documentation](https://actix.github.io/actix/actix/)
|
||||
properly configured actix system.
|
||||
|
||||
> For more information, check out the [actix documentation](https://actix.github.io/actix/actix/)
|
||||
> and [actix guide](https://actix.github.io/actix/guide/).
|
||||
|
@ -1,20 +1,21 @@
|
||||
# Application
|
||||
|
||||
Actix web provides some primitives to build web servers and applications with Rust.
|
||||
It provides routing, middlewares, pre-processing of requests, and post-processing of responses,
|
||||
Actix web provides various primitives to build web servers and applications with Rust.
|
||||
It provides routing, middlewares, pre-processing of requests, post-processing of responses,
|
||||
websocket protocol handling, multipart streams, etc.
|
||||
|
||||
All actix web servers are built around the `App` instance.
|
||||
It is used for registering routes for resources, and middlewares.
|
||||
It also stores application specific state that is shared across all handlers
|
||||
within same application.
|
||||
It is used for registering routes for resources and middlewares.
|
||||
It also stores application state shared across all handlers 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.
|
||||
If supplied prefix does not contain leading slash, it gets inserted.
|
||||
The prefix should consist of value path segments. i.e for an application with prefix `/app`
|
||||
any request with the paths `/app`, `/app/` or `/app/test` would match,
|
||||
but path `/application` would not match.
|
||||
If a supplied prefix does not contain leading slash, it is automatically inserted.
|
||||
The prefix should consist of value path segments.
|
||||
|
||||
> 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
|
||||
# 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
|
||||
gets created. This resource is available as on `/app/index.html` url.
|
||||
For more information check
|
||||
[*URL Matching*](./qs_5.html#using-a-application-prefix-to-compose-applications) section.
|
||||
In this example, an application with the `/app` prefix and a `index.html` resource
|
||||
are created. This resource is available through the `/app/index.html` url.
|
||||
|
||||
> 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:
|
||||
|
||||
@ -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.
|
||||
Applications get matched based on registration order, if an application with more general
|
||||
prefix is registered before a less generic one, that would effectively block the less generic
|
||||
application from getting matched. For example, if *application* with prefix "/" gets registered
|
||||
as first application, it would match all incoming requests.
|
||||
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 a more generic
|
||||
prefix is registered before a less generic one, it would effectively block the less generic
|
||||
application matching. For example, if an `App` with the prefix `"/"` was registered
|
||||
as the first application, it would match all incoming requests.
|
||||
|
||||
## State
|
||||
|
||||
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,
|
||||
but an interior mutability pattern with `RefCell` can be used to achieve state mutability.
|
||||
State can be accessed with `HttpContext::state()` when using an http actor.
|
||||
When using an http actor,state can be accessed with the `HttpRequest::state()` as read-only,
|
||||
but interior mutability with `RefCell` can be used to achieve state mutability.
|
||||
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
|
||||
@ -102,8 +103,8 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
Note on application state, http server accepts an application factory rather than an application
|
||||
instance. Http server constructs an application instance for each thread, so application state
|
||||
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`
|
||||
but the application factory must be `Send` + `Sync`.
|
||||
> **Note**: http server accepts an application factory rather than an application
|
||||
> 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
|
||||
> 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`.
|
||||
|
@ -1,13 +1,19 @@
|
||||
# Server
|
||||
|
||||
The [*HttpServer*](../actix_web/struct.HttpServer.html) type is responsible for
|
||||
serving http requests. *HttpServer* accepts application factory as a parameter,
|
||||
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.
|
||||
This method can be called multiple times. To start the http server, one of the *start*
|
||||
methods can be used. `start()` method starts a simple server, `start_tls()` or `start_ssl()`
|
||||
starts ssl server. *HttpServer* is an actix actor, it has to be initialized
|
||||
within a properly configured actix system:
|
||||
The [**HttpServer**](../actix_web/struct.HttpServer.html) type is responsible for
|
||||
serving http requests.
|
||||
|
||||
`HttpServer` accepts an application factory as a parameter, and the
|
||||
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, 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
|
||||
# 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
|
||||
case the server spawns a new thread and creates a new actix system in it. To stop
|
||||
this server, send a `StopServer` message.
|
||||
> 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
|
||||
> this server, send a `StopServer` message.
|
||||
|
||||
Http server 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
|
||||
address of the started http server. Actix http server accepts several messages:
|
||||
`HttpServer` is implemented as an actix actor. It is possible to communicate with the server
|
||||
via a messaging system. All start methods, e.g. `start()` and `start_ssl()`, return the
|
||||
address of the started http server. It accepts several messages:
|
||||
|
||||
* `PauseServer` - Pause accepting incoming connections
|
||||
* `ResumeServer` - Resume accepting incoming connections
|
||||
* `StopServer` - Stop incoming connection processing, stop all workers and exit
|
||||
- `PauseServer` - Pause accepting incoming connections
|
||||
- `ResumeServer` - Resume accepting incoming connections
|
||||
- `StopServer` - Stop incoming connection processing, stop all workers and exit
|
||||
|
||||
```rust
|
||||
# extern crate futures;
|
||||
@ -74,7 +80,7 @@ fn main() {
|
||||
|
||||
## 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
|
||||
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
|
||||
is not shared between threads, to share state `Arc` could be used. Application state
|
||||
does not need to be `Send` and `Sync` but application factory must be `Send` + `Sync`.
|
||||
is not shared between threads. To share state, `Arc` could be used.
|
||||
|
||||
> Application state does not need to be `Send` and `Sync`,
|
||||
> but factories must be `Send` + `Sync`.
|
||||
|
||||
## SSL
|
||||
|
||||
@ -123,22 +131,21 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
Note on *HTTP/2.0* protocol over tls without prior knowledge, it requires
|
||||
[tls alpn](https://tools.ietf.org/html/rfc7301). At the moment only
|
||||
`openssl` has `alpn ` support.
|
||||
|
||||
Please check [example](https://github.com/actix/actix-web/tree/master/examples/tls)
|
||||
for a full example.
|
||||
> **Note**: the *HTTP/2.0* protocol requires
|
||||
> [tls alpn](https://tools.ietf.org/html/rfc7301).
|
||||
> At the moment, only `openssl` has `alpn` support.
|
||||
> For a full example, check out
|
||||
> [examples/tls](https://github.com/actix/actix-web/tree/master/examples/tls).
|
||||
|
||||
## Keep-Alive
|
||||
|
||||
Actix can wait for requests on a keep-alive connection. *Keep alive*
|
||||
connection behavior is defined by server settings.
|
||||
Actix can wait for requests on a keep-alive connection.
|
||||
|
||||
* `75` or `Some(75)` or `KeepAlive::Timeout(75)` - enable 75 sec *keep alive* timer according
|
||||
request and response settings.
|
||||
* `None` or `KeepAlive::Disabled` - disable *keep alive*.
|
||||
* `KeepAlive::Tcp(75)` - Use `SO_KEEPALIVE` socket option.
|
||||
> *keep alive* connection behavior is defined by server settings.
|
||||
|
||||
- `75`, `Some(75)`, `KeepAlive::Timeout(75)` - enable 75 second *keep alive* timer.
|
||||
- `None` or `KeepAlive::Disabled` - disable *keep alive*.
|
||||
- `KeepAlive::Tcp(75)` - use `SO_KEEPALIVE` socket option.
|
||||
|
||||
```rust
|
||||
# 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
|
||||
`HttpResponse::connection_type` is not defined in that case *keep alive*
|
||||
defined by request's http version. Keep alive is off for *HTTP/1.0*
|
||||
and is on for *HTTP/1.1* and *HTTP/2.0*.
|
||||
`HttpResponse::connection_type` is not defined. In that case *keep alive* is
|
||||
defined by the request's http version.
|
||||
|
||||
> *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.
|
||||
|
||||
@ -186,19 +194,19 @@ fn index(req: HttpRequest) -> HttpResponse {
|
||||
|
||||
## Graceful shutdown
|
||||
|
||||
Actix http server supports graceful shutdown. After receiving a stop signal, workers
|
||||
have a specific amount of time to finish serving requests. Workers still alive after the
|
||||
`HttpServer` supports graceful shutdown. After receiving a stop signal, workers
|
||||
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.
|
||||
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
|
||||
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.
|
||||
|
||||
* *SIGINT* - Force shutdown workers
|
||||
* *SIGTERM* - Graceful shutdown workers
|
||||
* *SIGQUIT* - Force shutdown workers
|
||||
- *SIGINT* - Force shutdown workers
|
||||
- *SIGTERM* - Graceful 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.
|
||||
|
@ -1,17 +1,18 @@
|
||||
# Handler
|
||||
|
||||
A request handler can be any object that implements
|
||||
[*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
|
||||
[*Responder trait*](../actix_web/trait.Responder.html#foreign-impls).
|
||||
Then `respond_to()` is called on the returned object. And finally
|
||||
result of the `respond_to()` call is converted to a `Reply` object.
|
||||
[`Handler` trait](../actix_web/dev/trait.Handler.html).
|
||||
|
||||
Request handling happens in two stages. First the handler object is called,
|
||||
returning any object that implements the
|
||||
[`Responder` trait](../actix_web/trait.Responder.html#foreign-impls).
|
||||
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,
|
||||
like `&'static str`, `String`, etc.
|
||||
For a complete list of implementations, check
|
||||
[*Responder documentation*](../actix_web/trait.Responder.html#foreign-impls).
|
||||
such as `&'static str`, `String`, etc.
|
||||
|
||||
> For a complete list of implementations, check
|
||||
> [*Responder documentation*](../actix_web/trait.Responder.html#foreign-impls).
|
||||
|
||||
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 application state type. So
|
||||
application state is accessible from handler with the `HttpRequest::state()` method.
|
||||
But state is accessible as a read-only reference - if you need mutable access to state
|
||||
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
|
||||
of application state and handlers, unique for each thread, so if you run your
|
||||
application in several threads, actix will create the same amount as number of threads
|
||||
of application state objects and handler objects.
|
||||
*Handler* trait is generic over *S*, which defines the application state's type.
|
||||
Application state is accessible from the handler with the `HttpRequest::state()` method;
|
||||
however, state is accessible as a read-only reference. If you need mutable access to state,
|
||||
it must be implemented.
|
||||
|
||||
> **Note**: Alternatively, the handler can mutably access its own state because the `handle` method takes
|
||||
> mutable reference to *self*. **Beware**, actix creates multiple copies
|
||||
> of the application state and the handlers, unique for each thread. If you run your
|
||||
> 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:
|
||||
|
||||
@ -69,8 +71,8 @@ impl<S> Handler<S> for MyHandler {
|
||||
# fn main() {}
|
||||
```
|
||||
|
||||
This handler will work, but `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`
|
||||
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`.
|
||||
|
||||
```rust
|
||||
# extern crate actix;
|
||||
@ -111,14 +113,15 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
Be careful with synchronization primitives like *Mutex* or *RwLock*. Actix web framework
|
||||
handles requests asynchronously; by blocking thread execution all concurrent
|
||||
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.
|
||||
> Be careful with synchronization primitives like `Mutex` or `RwLock`. Actix web framework
|
||||
> handles requests asynchronously. By blocking thread execution, all concurrent
|
||||
> 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.
|
||||
|
||||
## 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:
|
||||
|
||||
```rust
|
||||
@ -171,10 +174,10 @@ fn main() {
|
||||
|
||||
## 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
|
||||
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:
|
||||
In this case, the handler must return a `Future` object that resolves to the *Responder* type, i.e:
|
||||
|
||||
```rust
|
||||
# extern crate actix_web;
|
||||
@ -205,8 +208,8 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
Or the response body can be generated asynchronously. In this case body
|
||||
must implement stream trait `Stream<Item=Bytes, Error=Error>`, i.e:
|
||||
Or the response body can be generated asynchronously. In this case, body
|
||||
must implement the stream trait `Stream<Item=Bytes, Error=Error>`, i.e:
|
||||
|
||||
```rust
|
||||
# extern crate actix_web;
|
||||
@ -233,7 +236,7 @@ fn main() {
|
||||
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`.
|
||||
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`.
|
||||
|
||||
```rust
|
||||
@ -265,11 +268,11 @@ fn index(req: HttpRequest) -> Result<Box<Future<Item=HttpResponse, Error=Error>>
|
||||
|
||||
## Different return types (Either)
|
||||
|
||||
Sometimes you need to return different types of responses. For example
|
||||
you can do error check and return error and return async response otherwise.
|
||||
Or any result that requires two different types.
|
||||
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.
|
||||
Sometimes, you need to return different types of responses. For example,
|
||||
you can error check and return errors, return async responses, or any result that requires two different types.
|
||||
|
||||
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.
|
||||
|
||||
```rust
|
||||
# extern crate actix_web;
|
||||
|
@ -1,10 +1,11 @@
|
||||
# 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)
|
||||
for handling handler's errors.
|
||||
|
||||
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
|
||||
definition:
|
||||
|
||||
@ -12,7 +13,8 @@ definition:
|
||||
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
|
||||
into an `HttpInternalServerError` response. Implementation for `io::Error` is provided
|
||||
by default.
|
||||
@ -35,7 +37,7 @@ fn index(req: HttpRequest) -> io::Result<fs::NamedFile> {
|
||||
|
||||
## 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 `error_response()` method: it generates a *500* response.
|
||||
|
||||
@ -109,7 +111,7 @@ fn index(req: HttpRequest) -> Result<&'static str, MyError> {
|
||||
## Error helpers
|
||||
|
||||
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
|
||||
# extern crate actix_web;
|
||||
|
@ -2,17 +2,19 @@
|
||||
|
||||
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,
|
||||
a particular handler object is invoked. 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).
|
||||
a particular handler object is invoked.
|
||||
|
||||
> 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 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.
|
||||
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*,
|
||||
it does not match against the *QUERY* portion (the portion following the scheme and
|
||||
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
|
||||
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
|
||||
@ -43,7 +45,7 @@ The *Configuration function* has the following type:
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
## 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
|
||||
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
|
||||
any number of *predicates* but only one handler.
|
||||
the order the routes were registered via `Resource::route()`.
|
||||
|
||||
> A *Route* can contain any number of *predicates* but only one handler.
|
||||
|
||||
```rust
|
||||
# extern crate actix_web;
|
||||
@ -74,10 +77,11 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
In this example `HttpResponse::Ok()` is returned for *GET* requests,
|
||||
if request contains `Content-Type` header and value of this header is *text/plain*
|
||||
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.
|
||||
In this example, `HttpResponse::Ok()` is returned for *GET* requests.
|
||||
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.
|
||||
|
||||
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
|
||||
[*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.
|
||||
|
||||
If any route matches, the route matching process stops and the handler associated with
|
||||
the route is invoked.
|
||||
|
||||
If no route matches after all route patterns are exhausted, a *NOT FOUND* response get returned.
|
||||
the route is invoked. If no route matches after all route patterns are exhausted, a *NOT FOUND* response get returned.
|
||||
|
||||
## Resource pattern syntax
|
||||
|
||||
@ -208,8 +210,9 @@ For example, for the URL */abc/*:
|
||||
* */abc/{foo}* will not match.
|
||||
* */{foo}/* will match.
|
||||
|
||||
Note that 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.
|
||||
> **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.
|
||||
|
||||
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,
|
||||
an `Err` is returned indicating the condition met:
|
||||
|
||||
* Decoded segment starts with any of: `.` (except `..`), `*`
|
||||
* Decoded segment ends with any of: `:`, `>`, `<`
|
||||
* Decoded segment contains any of: `/`
|
||||
* On Windows, decoded segment contains any of: '\'
|
||||
* Percent-encoding results in invalid UTF8.
|
||||
* Decoded segment starts with any of: `.` (except `..`), `*`
|
||||
* Decoded segment ends with any of: `:`, `>`, `<`
|
||||
* Decoded segment contains any of: `/`
|
||||
* On Windows, decoded segment contains any of: '\'
|
||||
* Percent-encoding results in invalid UTF8.
|
||||
|
||||
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.
|
||||
@ -350,8 +353,8 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
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.
|
||||
It also possible to extract path information to a tuple. In this case, you don't need
|
||||
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.
|
||||
|
||||
@ -433,21 +436,21 @@ fn main() {
|
||||
|
||||
By normalizing it means:
|
||||
|
||||
- Add a trailing slash to the path.
|
||||
- Double slashes are replaced by one.
|
||||
* Add a trailing slash to the path.
|
||||
* Double slashes are replaced by one.
|
||||
|
||||
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
|
||||
and 3) append. If the path resolves with
|
||||
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
|
||||
be appended automatically.
|
||||
|
||||
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
|
||||
# extern crate actix_web;
|
||||
@ -468,7 +471,7 @@ fn main() {
|
||||
|
||||
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
|
||||
slash-appending *Not Found* will turn a *POST* request into a GET, losing any
|
||||
*POST* data in the original request.
|
||||
@ -493,7 +496,7 @@ fn main() {
|
||||
|
||||
## 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
|
||||
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
|
||||
@ -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()`.
|
||||
Also predicates can store extra information in
|
||||
@ -565,7 +568,7 @@ Also predicates can store extra information in
|
||||
### Modifying predicate values
|
||||
|
||||
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":
|
||||
|
||||
```rust
|
||||
|
Loading…
Reference in New Issue
Block a user