1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-09-09 05:08:32 +00:00

Merge pull request #138 from bwasty/guide

Guide: improve wording & style
This commit is contained in:
Nikolay Kim 2018-03-28 13:40:05 -07:00 committed by GitHub
commit 80f6b93714
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 303 additions and 305 deletions

View file

@ -1,6 +1,6 @@
# Quick start # Quick start
Before you can start writing a actix web application, youll need a version of Rust installed. 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. We recommend you use rustup to install or configure such a version.
## Install Rust ## Install Rust

View file

@ -1,23 +1,23 @@
# Middlewares # Middleware
Actix middlewares system allows to add additional behavior to request/response processing. Actix' middleware system allows to add additional behavior to request/response processing.
Middleware can hook into incoming request process and modify request or halt request Middleware can hook into incoming request process and modify request or halt request
processing and return response early. Also it can hook into response processing. processing and return response early. Also it can hook into response processing.
Typically middlewares involves in following actions: Typically middlewares are involved in the following actions:
* Pre-process the Request * Pre-process the Request
* Post-process a Response * Post-process a Response
* Modify application state * Modify application state
* Access external services (redis, logging, sessions) * Access external services (redis, logging, sessions)
Middlewares are registered for each application and get executed in same order as Middlewares are registered for each application and are executed in same order as
registration order. In general, *middleware* is a type that implements registration order. In general, a *middleware* is a type that implements the
[*Middleware trait*](../actix_web/middlewares/trait.Middleware.html). Each method [*Middleware trait*](../actix_web/middlewares/trait.Middleware.html). Each method
in this trait has default implementation. Each method can return result immediately in this trait has a default implementation. Each method can return a result immediately
or *future* object. or a *future* object.
Here is example of simple middleware that adds request and response headers: Here is an example of a simple middleware that adds request and response headers:
```rust ```rust
# extern crate http; # extern crate http;
@ -52,26 +52,26 @@ impl<S> Middleware<S> for Headers {
fn main() { fn main() {
Application::new() Application::new()
.middleware(Headers) // <- Register middleware, this method could be called multiple times .middleware(Headers) // <- Register middleware, this method can be called multiple times
.resource("/", |r| r.h(httpcodes::HttpOk)); .resource("/", |r| r.h(httpcodes::HttpOk));
} }
``` ```
Active provides several useful middlewares, like *logging*, *user sessions*, etc. Actix provides several useful middlewares, like *logging*, *user sessions*, etc.
## Logging ## Logging
Logging is implemented as middleware. Logging is implemented as a middleware.
It is common to register logging middleware as first middleware for application. It is common to register a logging middleware as the first middleware for the application.
Logging middleware has to be registered for each application. *Logger* middleware Logging middleware has to be registered for each application. *Logger* middleware
uses standard log crate to log information. You should enable logger for *actix_web* uses the standard log crate to log information. You should enable logger for *actix_web*
package to see access log. ([env_logger](https://docs.rs/env_logger/*/env_logger/) or similar) package to see access log ([env_logger](https://docs.rs/env_logger/*/env_logger/) or similar).
### Usage ### Usage
Create `Logger` middleware with the specified `format`. Create `Logger` middleware with the specified `format`.
Default `Logger` could be created with `default` method, it uses the default format: Default `Logger` can be created with `default` method, it uses the default format:
```ignore ```ignore
%a %t "%r" %s %b "%{Referer}i" "%{User-Agent}i" %T %a %t "%r" %s %b "%{Referer}i" "%{User-Agent}i" %T
@ -93,7 +93,7 @@ fn main() {
} }
``` ```
Here is example of default logging format: Here is an example of the default logging format:
``` ```
INFO:actix_web::middleware::logger: 127.0.0.1:59934 [02/Dec/2017:00:21:43 -0800] "GET / HTTP/1.1" 302 0 "-" "curl/7.54.0" 0.000397 INFO:actix_web::middleware::logger: 127.0.0.1:59934 [02/Dec/2017:00:21:43 -0800] "GET / HTTP/1.1" 302 0 "-" "curl/7.54.0" 0.000397
@ -129,9 +129,9 @@ INFO:actix_web::middleware::logger: 127.0.0.1:59947 [02/Dec/2017:00:22:40 -0800]
## Default headers ## Default headers
To set default response headers `DefaultHeaders` middleware could be used. To set default response headers the `DefaultHeaders` middleware can be used. The
*DefaultHeaders* middleware does not set header if response headers already contains *DefaultHeaders* middleware does not set the header if response headers already contain
specified header. the specified header.
```rust ```rust
# extern crate actix_web; # extern crate actix_web;
@ -153,16 +153,16 @@ fn main() {
## User sessions ## User sessions
Actix provides general solution for session management. Actix provides a general solution for session management. The
[*Session storage*](../actix_web/middleware/struct.SessionStorage.html) middleware can be [*Session storage*](../actix_web/middleware/struct.SessionStorage.html) middleware can be
use with different backend types to store session data in different backends. used with different backend types to store session data in different backends.
By default only cookie session backend is implemented. Other backend implementations By default only cookie session backend is implemented. Other backend implementations
could be added later. could be added later.
[*Cookie session backend*](../actix_web/middleware/struct.CookieSessionBackend.html) [*Cookie session backend*](../actix_web/middleware/struct.CookieSessionBackend.html)
uses signed cookies as session storage. *Cookie session backend* creates sessions which uses signed cookies as session storage. *Cookie session backend* creates sessions which
are limited to storing fewer than 4000 bytes of data (as the payload must fit into a are limited to storing fewer than 4000 bytes of data (as the payload must fit into a
single cookie). Internal server error get generated if session contains more than 4000 bytes. single cookie). Internal server error is generated if session contains more than 4000 bytes.
You need to pass a random value to the constructor of *CookieSessionBackend*. You need to pass a random value to the constructor of *CookieSessionBackend*.
This is private key for cookie session. When this value is changed, all session data is lost. This is private key for cookie session. When this value is changed, all session data is lost.
@ -173,7 +173,7 @@ In general case, you create
and initializes it with specific backend implementation, like *CookieSessionBackend*. and initializes it with specific backend implementation, like *CookieSessionBackend*.
To access session data To access session data
[*HttpRequest::session()*](../actix_web/middleware/trait.RequestSession.html#tymethod.session) [*HttpRequest::session()*](../actix_web/middleware/trait.RequestSession.html#tymethod.session)
method has to be used. This method returns has to be used. This method returns a
[*Session*](../actix_web/middleware/struct.Session.html) object, which allows to get or set [*Session*](../actix_web/middleware/struct.Session.html) object, which allows to get or set
session data. session data.

View file

@ -24,9 +24,9 @@ fn main() {
## Directory ## Directory
To serve files from specific directory and sub-directories `StaticFiles` could be used. To serve files from specific directory and sub-directories `StaticFiles` could be used.
`StaticFiles` must be registered with `Application::handler()` method otherwise `StaticFiles` must be registered with `Application::handler()` method otherwise
it won't be able to server sub-paths. it won't be able to serve sub-paths.
```rust ```rust
# extern crate actix_web; # extern crate actix_web;
@ -44,6 +44,6 @@ directory listing would be returned for directories, if it is set to *false*
then *404 Not Found* would be returned instead of directory listing. then *404 Not Found* would be returned instead of directory listing.
Instead of showing files listing for directory, it is possible to redirect to specific Instead of showing files listing for directory, it is possible to redirect to specific
index file. Use index file. Use
[*StaticFiles::index_file()*](../actix_web/s/struct.StaticFiles.html#method.index_file) [*StaticFiles::index_file()*](../actix_web/s/struct.StaticFiles.html#method.index_file)
method to configure this redirect. method to configure this redirect.

View file

@ -6,8 +6,8 @@ Actix web automatically upgrades connection to *HTTP/2.0* if possible.
*HTTP/2.0* protocol over tls without prior knowledge requires *HTTP/2.0* protocol over tls without prior knowledge requires
[tls alpn](https://tools.ietf.org/html/rfc7301). At the moment only [tls alpn](https://tools.ietf.org/html/rfc7301). At the moment only
`rust-openssl` has support. Turn on `alpn` feature to enable `alpn` negotiation. `rust-openssl` has support. Turn on the `alpn` feature to enable `alpn` negotiation.
With enable `alpn` feature `HttpServer` provides With enabled `alpn` feature `HttpServer` provides the
[serve_tls](../actix_web/struct.HttpServer.html#method.serve_tls) method. [serve_tls](../actix_web/struct.HttpServer.html#method.serve_tls) method.
```toml ```toml
@ -40,5 +40,5 @@ Upgrade to *HTTP/2.0* schema described in
Starting *HTTP/2* with prior knowledge is supported for both clear text connection Starting *HTTP/2* with prior knowledge is supported for both clear text connection
and tls connection. [rfc section 3.4](https://http2.github.io/http2-spec/#rfc.section.3.4) and tls connection. [rfc section 3.4](https://http2.github.io/http2-spec/#rfc.section.3.4)
Please check [example](https://github.com/actix/actix-web/tree/master/examples/tls) Please check [example](https://github.com/actix/actix-web/tree/master/examples/tls)
for concrete example. for a concrete example.

View file

@ -3,13 +3,13 @@
## Diesel ## Diesel
At the moment of 1.0 release Diesel does not support asynchronous operations. At the moment of 1.0 release Diesel does not support asynchronous operations.
But it possible to use `actix` synchronous actor system as a db interface api. But it possible to use the `actix` synchronous actor system as a db interface api.
Technically sync actors are worker style actors, multiple of them Technically sync actors are worker style actors, multiple of them
can be run in parallel and process messages from same queue (sync actors work in mpmc mode). can be run in parallel and process messages from same queue (sync actors work in mpsc mode).
Let's create simple db api that can insert new user row into sqlite table. Let's create a simple db api that can insert a new user row into an SQLite table.
We have to define sync actor and connection that this actor will use. Same approach We have to define sync actor and connection that this actor will use. The same approach
could be used for other databases. can be used for other databases.
```rust,ignore ```rust,ignore
use actix::prelude::*; use actix::prelude::*;
@ -21,7 +21,7 @@ impl Actor for DbExecutor {
} }
``` ```
This is definition of our actor. Now we need to define *create user* message and response. This is the definition of our actor. Now we need to define the *create user* message and response.
```rust,ignore ```rust,ignore
struct CreateUser { struct CreateUser {
@ -33,8 +33,8 @@ impl Message for CreateUser {
} }
``` ```
We can send `CreateUser` message to `DbExecutor` actor, and as result we get We can send a `CreateUser` message to the `DbExecutor` actor, and as a result we get a
`User` model. Now we need to define actual handler implementation for this message. `User` model instance. Now we need to define the actual handler implementation for this message.
```rust,ignore ```rust,ignore
impl Handler<CreateUser> for DbExecutor { impl Handler<CreateUser> for DbExecutor {
@ -67,8 +67,8 @@ impl Handler<CreateUser> for DbExecutor {
} }
``` ```
That is it. Now we can use *DbExecutor* actor from any http handler or middleware. That's it. Now we can use the *DbExecutor* actor from any http handler or middleware.
All we need is to start *DbExecutor* actors and store address in a state where http handler All we need is to start *DbExecutor* actors and store the address in a state where http handler
can access it. can access it.
```rust,ignore ```rust,ignore
@ -97,8 +97,8 @@ fn main() {
} }
``` ```
And finally we can use address in a request handler. We get message response And finally we can use the address in a request handler. We get a message response
asynchronously, so handler needs to return future object, also `Route::a()` needs to be asynchronously, so the handler needs to return a future object, also `Route::a()` needs to be
used for async handler registration. used for async handler registration.
@ -120,8 +120,8 @@ fn index(req: HttpRequest<State>) -> Box<Future<Item=HttpResponse, Error=Error>>
} }
``` ```
Full example is available in Full example is available in the
[examples directory](https://github.com/actix/actix-web/tree/master/examples/diesel/). [examples directory](https://github.com/actix/actix-web/tree/master/examples/diesel/).
More information on sync actors could be found in More information on sync actors can be found in the
[actix documentation](https://docs.rs/actix/0.5.0/actix/sync/index.html). [actix documentation](https://docs.rs/actix/0.5.0/actix/sync/index.html).

View file

@ -3,9 +3,9 @@
Lets create and run our first actix web application. Well create a new Cargo project Lets create and run our first actix web application. Well create a new Cargo project
that depends on actix web and then run the application. that depends on actix web and then run the application.
In previous section we already installed required rust version. Now let's create new cargo projects. 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 Lets write our first actix web application! Start by creating a new binary-based
Cargo project and changing into the new directory: Cargo project and changing into the new directory:
@ -15,7 +15,7 @@ cargo new hello-world --bin
cd hello-world cd hello-world
``` ```
Now, add actix and actix web as dependencies of your project by ensuring your Cargo.toml Now, add actix and actix web as dependencies of your project by ensuring your Cargo.toml
contains the following: contains the following:
```toml ```toml
@ -26,7 +26,7 @@ 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, first we need to create a request handler.
A request handler is a function that accepts a `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`:
```rust ```rust
@ -53,8 +53,8 @@ request handler with the application's `resource` on a particular *HTTP method*
# } # }
``` ```
After that, application instance can be used with `HttpServer` to listen for incoming After that, the application instance can be used with `HttpServer` to listen for incoming
connections. Server accepts function that should return `HttpHandler` instance: connections. The server accepts a function that should return an `HttpHandler` instance:
```rust,ignore ```rust,ignore
HttpServer::new( HttpServer::new(
@ -64,7 +64,7 @@ connections. Server accepts function that should return `HttpHandler` instance:
.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: Here is full source of main.rs file:
@ -92,7 +92,7 @@ fn main() {
} }
``` ```
Note on `actix` crate. Actix web framework is built on top of actix actor library. Note on the `actix` crate. Actix web framework is built on top of actix actor library.
`actix::System` initializes actor system, `HttpServer` is an actor and must run within `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. For more information please check
[actix documentation](https://actix.github.io/actix/actix/) [actix documentation](https://actix.github.io/actix/actix/)

View file

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

View file

@ -1,13 +1,13 @@
# Server # Server
[*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* accept application factory as a parameter, serving http requests. *HttpServer* accepts application factory as a parameter,
Application factory must have `Send` + `Sync` boundaries. More about that in Application factory must have `Send` + `Sync` boundaries. More about that in the
*multi-threading* section. To bind to specific socket address `bind()` must be used. *multi-threading* section. To bind to a specific socket address, `bind()` must be used.
This method could be called multiple times. To start http server one of the *start* This method can be called multiple times. To start the http server, one of the *start*
methods could be used. `start()` method start simple server, `start_tls()` or `start_ssl()` 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 starts ssl server. *HttpServer* is an actix actor, it has to be initialized
within properly configured actix system: within a properly configured actix system:
```rust ```rust
# extern crate actix; # extern crate actix;
@ -29,13 +29,13 @@ fn main() {
} }
``` ```
It is possible to start server in separate thread with *spawn()* method. In that It is possible to start a server in a separate thread with the *spawn()* method. In that
case server spawns new thread and create 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 `StopServer` message. this server, send a `StopServer` message.
Http server is implemented as an actix actor. It is possible to communicate with server Http server is implemented as an actix actor. It is possible to communicate with the server
via messaging system. All start methods like `start()`, `start_ssl()`, etc returns via a messaging system. All start methods like `start()`, `start_ssl()`, etc. return the
address of the started http server. Actix http server accept several messages: address of the started http server. Actix http server accepts several messages:
* `PauseServer` - Pause accepting incoming connections * `PauseServer` - Pause accepting incoming connections
* `ResumeServer` - Resume accepting incoming connections * `ResumeServer` - Resume accepting incoming connections
@ -73,9 +73,9 @@ fn main() {
## Multi-threading ## Multi-threading
Http server automatically starts number of http workers, by default Http server automatically starts an number of http workers, by default
this number is equal to number of logical cpu in the system. This number this number is equal to number of logical CPUs in the system. This number
could be overridden with `HttpServer::threads()` method. can be overridden with the `HttpServer::threads()` method.
```rust ```rust
# extern crate actix_web; # extern crate actix_web;
@ -90,13 +90,13 @@ fn main() {
} }
``` ```
Server create 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. Application state
does not need to be `Send` and `Sync` but application factory must be `Send` + `Sync`. does not need to be `Send` and `Sync` but application factory must be `Send` + `Sync`.
## SSL ## SSL
There are two `tls` and `alpn` features for ssl server. `tls` feature is for `native-tls` There are two features for ssl server: `tls` and `alpn`. The `tls` feature is for `native-tls`
integration and `alpn` is for `openssl`. integration and `alpn` is for `openssl`.
```toml ```toml
@ -127,7 +127,7 @@ Note on *HTTP/2.0* protocol over tls without prior knowledge, it requires
`openssl` has `alpn ` support. `openssl` has `alpn ` support.
Please check [example](https://github.com/actix/actix-web/tree/master/examples/tls) Please check [example](https://github.com/actix/actix-web/tree/master/examples/tls)
for full example. for a full example.
## Keep-Alive ## Keep-Alive
@ -162,13 +162,13 @@ fn main() {
} }
``` ```
If first option is selected then *keep alive* state If first option is selected then *keep alive* state is
calculated based on 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*
defined by request's http version. Keep alive is off for *HTTP/1.0* 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*. and is on for *HTTP/1.1* and *HTTP/2.0*.
*Connection type* could be change with `HttpResponseBuilder::connection_type()` method. *Connection type* can be change with `HttpResponseBuilder::connection_type()` method.
```rust ```rust
# extern crate actix_web; # extern crate actix_web;
@ -186,13 +186,13 @@ fn index(req: HttpRequest) -> HttpResponse {
## Graceful shutdown ## Graceful shutdown
Actix http server support graceful shutdown. After receiving a stop signal, workers Actix http server supports graceful shutdown. After receiving a stop signal, workers
have specific amount of time to finish serving requests. Workers still alive after the have a specific amount of time to finish serving requests. Workers still alive after the
timeout are force dropped. By default shutdown timeout sets to 30 seconds. timeout are force-dropped. By default the shutdown timeout is set to 30 seconds.
You can change this parameter with `HttpServer::shutdown_timeout()` method. You can change this parameter with the `HttpServer::shutdown_timeout()` method.
You can send stop message to server with server address and specify if you what You can send a stop message to the server with the server address and specify if you want
graceful shutdown or not. `start()` methods return address of the server. graceful shutdown or not. The `start()` methods return address of the server.
Http server handles several OS signals. *CTRL-C* is available on all OSs, Http server 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.
@ -201,4 +201,4 @@ other signals are available on unix systems.
* *SIGTERM* - Graceful shutdown workers * *SIGTERM* - Graceful shutdown workers
* *SIGQUIT* - Force shutdown workers * *SIGQUIT* - Force shutdown workers
It is possible to disable signals handling with `HttpServer::disable_signals()` method. It is possible to disable signal handling with `HttpServer::disable_signals()` method.

View file

@ -1,16 +1,16 @@
# Handler # Handler
A request handler can by 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 happen in two stages. First handler object get called. Request handling happens in two stages. First the handler object is called.
Handle can return any object that implements Handler can return any object that implements
[*Responder trait*](../actix_web/trait.Responder.html#foreign-impls). [*Responder trait*](../actix_web/trait.Responder.html#foreign-impls).
Then `respond_to()` get called on returned object. And finally Then `respond_to()` is called on the returned object. And finally
result of the `respond_to()` call get converted to `Reply` object. result of the `respond_to()` call is converted to a `Reply` object.
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. like `&'static str`, `String`, etc.
For complete list of implementations check For a complete list of implementations, check
[*Responder documentation*](../actix_web/trait.Responder.html#foreign-impls). [*Responder documentation*](../actix_web/trait.Responder.html#foreign-impls).
Examples of valid handlers: Examples of valid handlers:
@ -41,15 +41,15 @@ fn index(req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> {
Some notes on shared application state and handler state. If you noticed Some notes on shared application state and handler state. If you noticed
*Handler* trait is generic over *S*, which defines application state type. So *Handler* trait is generic over *S*, which defines application state type. So
application state is accessible from handler with `HttpRequest::state()` method. 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 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 mutable access it's own state you have to implement it yourself. On other hand, handler can mutably access its own state
as `handle` method takes mutable reference to *self*. Beware, actix creates multiple copies 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 of application state and handlers, unique for each thread, so if you run your
application in several threads actix will create same amount as number of threads application in several threads, actix will create the same amount as number of threads
of application state objects and handler objects. of application state objects and handler objects.
Here is example of handler that stores number of processed requests: Here is an example of a handler that stores the number of processed requests:
```rust ```rust
# extern crate actix; # extern crate actix;
@ -71,8 +71,8 @@ impl<S> Handler<S> for MyHandler {
# fn main() {} # fn main() {}
``` ```
This handler will work, but `self.0` value will be different depends on number of threads and This handler will work, but `self.0` will be different depending on the number of threads and
number of requests processed per thread. 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;
@ -100,7 +100,7 @@ fn main() {
let inc = Arc::new(AtomicUsize::new(0)); let inc = Arc::new(AtomicUsize::new(0));
HttpServer::new( HttpServer::new(
move || { move || {
let cloned = inc.clone(); let cloned = inc.clone();
Application::new() Application::new()
.resource("/", move |r| r.h(MyHandler(cloned))) .resource("/", move |r| r.h(MyHandler(cloned)))
@ -115,14 +115,14 @@ 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 request 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 [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 custom type directly from handler function, type needs to implement `Responder` trait. To return a custom type directly from a handler function, the type needs to implement the `Responder` trait.
Let's create response for custom type that serializes to `application/json` response: Let's create a response for a custom type that serializes to an `application/json` response:
```rust ```rust
# extern crate actix; # extern crate actix;
@ -174,11 +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 object could be generated asynchronously or more precisely, any type Response objects can be generated asynchronously or more precisely, any type
that implements [*Responder*](../actix_web/trait.Responder.html) trait. In this case handle must 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:
return `Future` object that resolves to *Responder* type, i.e:
```rust ```rust
# extern crate actix_web; # extern crate actix_web;
@ -210,7 +209,7 @@ fn main() {
} }
``` ```
Or 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 stream trait `Stream<Item=Bytes, Error=Error>`, i.e:
```rust ```rust
@ -235,10 +234,10 @@ fn main() {
} }
``` ```
Both methods could be combined. (i.e Async response with streaming body) Both methods can be combined. (i.e Async response with streaming body)
It is possible return `Result` which `Result::Item` type could be `Future`. It is possible to return a `Result` where the `Result::Item` type can be `Future`.
In this example `index` handler can return error immediately or return 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
@ -273,8 +272,8 @@ fn index(req: HttpRequest) -> Result<Box<Future<Item=HttpResponse, Error=Error>>
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 do error check and return error and return async response otherwise.
Or any result that requires two different types. Or any result that requires two different types.
For this case [*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 to combine 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;
@ -308,9 +307,9 @@ fn index(req: HttpRequest) -> RegisterResult {
## Tokio core handle ## Tokio core handle
Any actix web handler runs within properly configured Any actix web handler runs within a properly configured
[actix system](https://actix.github.io/actix/actix/struct.System.html) [actix system](https://actix.github.io/actix/actix/struct.System.html)
and [arbiter](https://actix.github.io/actix/actix/struct.Arbiter.html). and [arbiter](https://actix.github.io/actix/actix/struct.Arbiter.html).
You can always get access to tokio handle via You can always get access to the tokio handle via the
[Arbiter::handle()](https://actix.github.io/actix/actix/struct.Arbiter.html#method.handle) [Arbiter::handle()](https://actix.github.io/actix/actix/struct.Arbiter.html#method.handle)
method. method.

View file

@ -1,20 +1,20 @@
# Errors # Errors
Actix uses [`Error` type](../actix_web/error/struct.Error.html) Actix uses [`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 `ResponseError` trait can be returned as error value. Any error that implements the `ResponseError` trait can be returned as an error value.
*Handler* can return *Result* object, actix by default provides *Handler* can return an *Result* object; actix by default provides
`Responder` implementation for compatible result types. Here is implementation `Responder` implementation for compatible result types. Here is the implementation
definition: definition:
```rust,ignore ```rust,ignore
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 `Error` object. And any error that implements `ResponseError` can be converted into an `Error` object.
For example if *handler* function returns `io::Error`, it would be converted For example, if the *handler* function returns `io::Error`, it would be converted
into `HttpInternalServerError` response. Implementation for `io::Error` is provided into an `HttpInternalServerError` response. Implementation for `io::Error` is provided
by default. by default.
```rust ```rust
@ -35,9 +35,9 @@ 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 `ResponseError` trait To add support for custom errors, all we need to do is just implement the `ResponseError` trait
for custom error. `ResponseError` trait has default implementation for the custom error type. The `ResponseError` trait has a default implementation
for `error_response()` method, it generates *500* response. for the `error_response()` method: it generates a *500* response.
```rust ```rust
# extern crate actix_web; # extern crate actix_web;
@ -64,8 +64,8 @@ fn index(req: HttpRequest) -> Result<&'static str, MyError> {
# } # }
``` ```
In this example *index* handler always returns *500* response. But it is easy In this example the *index* handler always returns a *500* response. But it is easy
to return different responses for different type of errors. to return different responses for different types of errors.
```rust ```rust
# extern crate actix_web; # extern crate actix_web;
@ -108,7 +108,7 @@ fn index(req: HttpRequest) -> Result<&'static str, MyError> {
## Error helpers ## Error helpers
Actix provides set of error helper types. It is possible to use them to generate 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 helper types for the first example with custom error.
```rust ```rust
@ -123,7 +123,7 @@ struct MyError {
fn index(req: HttpRequest) -> Result<&'static str> { fn index(req: HttpRequest) -> Result<&'static str> {
let result: Result<&'static str, MyError> = Err(MyError{name: "test"}); let result: Result<&'static str, MyError> = Err(MyError{name: "test"});
Ok(result.map_err(|e| error::ErrorBadRequest(e))?) Ok(result.map_err(|e| error::ErrorBadRequest(e))?)
} }
# fn main() { # fn main() {
@ -133,18 +133,18 @@ fn index(req: HttpRequest) -> Result<&'static str> {
# } # }
``` ```
In this example *BAD REQUEST* response get generated for `MyError` error. In this example, a *BAD REQUEST* response is generated for the `MyError` error.
## Error logging ## Error logging
Actix logs all errors with `WARN` log level. If log level set to `DEBUG` Actix logs all errors with the log level `WARN`. If log level set to `DEBUG`
and `RUST_BACKTRACE` is enabled, backtrace get logged. The Error type uses and `RUST_BACKTRACE` is enabled, the backtrace gets logged. The Error type uses
cause's error backtrace if available, if the underlying failure does not provide the cause's error backtrace if available. If the underlying failure does not provide
a backtrace, a new backtrace is constructed pointing to that conversion point a backtrace, a new backtrace is constructed pointing to that conversion point
(rather than the origin of the error). This construction only happens if there (rather than the origin of the error). This construction only happens if there
is no underlying backtrace; if it does have a backtrace no new backtrace is constructed. is no underlying backtrace; if it does have a backtrace, no new backtrace is constructed.
You can enable backtrace and debug logging with following command: You can enable backtrace and debug logging with following command:
``` ```
>> RUST_BACKTRACE=1 RUST_LOG=actix_web=debug cargo run >> RUST_BACKTRACE=1 RUST_LOG=actix_web=debug cargo run

View file

@ -1,23 +1,23 @@
# URL Dispatch # URL Dispatch
URL dispatch provides a simple way to map URLs to `Handler` code using a simple pattern matching URL dispatch provides a simple way for mapping URLs to `Handler` code using a simple pattern
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 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 `Handler` trait, defined in your application, that receives the request and returns
a response object. More information is available in [handler section](../qs_4.html). 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 resource 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 *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 [Application::resource](../actix_web/struct.Application.html#method.resource) methods The [Application::resource](../actix_web/struct.Application.html#method.resource) methods
add a single resource to application routing table. This method accepts *path pattern* add a single resource to application routing table. This method accepts a *path pattern*
and resource configuration function. and a resource configuration function.
```rust ```rust
# extern crate actix_web; # extern crate actix_web;
@ -37,26 +37,26 @@ fn main() {
} }
``` ```
*Configuration function* has following type: The *Configuration function* has the following type:
```rust,ignore ```rust,ignore
FnOnce(&mut Resource<_>) -> () FnOnce(&mut Resource<_>) -> ()
``` ```
*Configuration function* can set name and register specific routes. The *Configuration function* can set a name and register specific routes.
If 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 resources. returns *NOT FOUND* http response.
## Configuring a Route ## Configuring a Route
Resource contains set of routes. Each route in turn has set of predicates and handler. Resource contains a set of routes. Each route in turn has a set of predicates and a handler.
New route could be created with `Resource::route()` method which returns reference New routes can be created with `Resource::route()` method which returns a reference
to new *Route* instance. By default *route* does not contain any predicates, so matches to new *Route* instance. By default the *route* does not contain any predicates, so matches
all requests and default handler is `HttpNotFound`. all requests and the default handler is `HttpNotFound`.
Application routes incoming requests based on route criteria which is 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 that the routes were registered via `Resource::route()`. *Route* can contain the order the routes were registered via `Resource::route()`. A *Route* can contain
any number of *predicates* but only one handler. any number of *predicates* but only one handler.
```rust ```rust
@ -76,30 +76,30 @@ fn main() {
} }
``` ```
In this example `index` get called for *GET* request, In this example `HttpOk` is returned for *GET* requests,
if request contains `Content-Type` header and value of this header is *text/plain* if request contains `Content-Type` header and value of this header is *text/plain*
and path equals to `/test`. Resource calls handle of the first matches route. and path equals to `/path`. Resource calls handle of the first matching route.
If resource can not match any route "NOT FOUND" response get returned. If a resource can not match any route a "NOT FOUND" response is returned.
[*Resource::route()*](../actix_web/struct.Resource.html#method.route) method returns [*Resource::route()*](../actix_web/struct.Resource.html#method.route) returns a
[*Route*](../actix_web/struct.Route.html) object. Route can be configured with [*Route*](../actix_web/struct.Route.html) object. Route can be configured with a
builder-like pattern. Following configuration methods are available: builder-like pattern. Following configuration methods are available:
* [*Route::filter()*](../actix_web/struct.Route.html#method.filter) method registers new predicate, * [*Route::filter()*](../actix_web/struct.Route.html#method.filter) registers a new predicate.
any number of predicates could be registered for each route. Any number of predicates can be registered for each route.
* [*Route::f()*](../actix_web/struct.Route.html#method.f) method registers handler function * [*Route::f()*](../actix_web/struct.Route.html#method.f) registers handler function
for this route. Only one handler could be registered. Usually handler registration for this route. Only one handler can be registered. Usually handler registration
is the last config operation. Handler function could be function or closure and has type is the last config operation. Handler function can be a function or closure and has the type
`Fn(HttpRequest<S>) -> R + 'static` `Fn(HttpRequest<S>) -> R + 'static`
* [*Route::h()*](../actix_web/struct.Route.html#method.h) method registers handler object * [*Route::h()*](../actix_web/struct.Route.html#method.h) registers a handler object
that implements `Handler` trait. This is similar to `f()` method, only one handler could that implements the `Handler` trait. This is similar to `f()` method - only one handler can
be registered. Handler registration is the last config operation. be registered. Handler registration is the last config operation.
* [*Route::a()*](../actix_web/struct.Route.html#method.a) method registers async handler * [*Route::a()*](../actix_web/struct.Route.html#method.a) registers an async handler
function for this route. Only one handler could be registered. Handler registration function for this route. Only one handler can be registered. Handler registration
is the last config operation. Handler function could be function or closure and has type is the last config operation. Handler function can be a function or closure and has the type
`Fn(HttpRequest<S>) -> Future<Item = HttpResponse, Error = Error> + 'static` `Fn(HttpRequest<S>) -> Future<Item = HttpResponse, Error = Error> + 'static`
## Route matching ## Route matching
@ -110,8 +110,8 @@ against a URL path pattern. `path` represents the path portion of the URL that w
The way that *actix* does this is very simple. When a request enters the system, The way that *actix* does this is very simple. When a request enters the system,
for each resource configuration declaration present in the system, actix checks for each resource configuration declaration present in the system, actix checks
the request's path against the pattern declared. This checking happens in the order that the request's path against the pattern declared. This checking happens in the order that
the routes were declared via `Application::resource()` method. If resource could not be found, the routes were declared via `Application::resource()` method. If resource can not be found,
*default resource* get used as matched resource. the *default resource* is used as the matched resource.
When a route configuration is declared, it may contain route predicate arguments. All route When a route configuration is declared, it may contain route predicate arguments. All route
predicates associated with a route declaration must be `true` for the route configuration to predicates associated with a route declaration must be `true` for the route configuration to
@ -120,13 +120,13 @@ 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
route get invoked. the route is invoked.
If no route matches after all route patterns are exhausted, *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
The syntax of the pattern matching language used by the actix in the pattern The syntax of the pattern matching language used by actix in the pattern
argument is straightforward. argument is straightforward.
The pattern used in route configuration may start with a slash character. If the pattern The pattern used in route configuration may start with a slash character. If the pattern
@ -261,12 +261,12 @@ foo/abc/def/a/b/c -> Params{'bar':u'abc', 'tail': 'def/a/b/c'}
All values representing matched path segments are available in All values representing matched path segments are available in
[`HttpRequest::match_info`](../actix_web/struct.HttpRequest.html#method.match_info). [`HttpRequest::match_info`](../actix_web/struct.HttpRequest.html#method.match_info).
Specific value can be received with Specific values can be retrieved with
[`Params::get()`](../actix_web/dev/struct.Params.html#method.get) method. [`Params::get()`](../actix_web/dev/struct.Params.html#method.get).
Any matched parameter can be deserialized into specific type if this type Any matched parameter can be deserialized into a specific type if the type
implements `FromParam` trait. For example most of standard integer types implements the `FromParam` trait. For example most standard integer types
implements `FromParam` trait. i.e.: the trait, i.e.:
```rust ```rust
# extern crate actix_web; # extern crate actix_web;
@ -320,16 +320,15 @@ fn main() {
} }
``` ```
List of `FromParam` implementation could be found in List of `FromParam` implementations can be found in
[api docs](../actix_web/dev/trait.FromParam.html#foreign-impls) [api docs](../actix_web/dev/trait.FromParam.html#foreign-impls)
## Path information extractor ## Path information extractor
Actix provides functionality for type safe request's path information extraction. Actix provides functionality for type safe request path information extraction.
It uses *serde* package as a deserialization library. It uses *serde* package as a deserialization library.
[HttpRequest::extract_path()](../actix_web/struct.HttpRequest.html#method.extract_path) [HttpRequest::extract_path()](../actix_web/struct.HttpRequest.html#method.extract_path)
method extracts information, destination type has to implements `Deserialize` trait extracts information, the destination type has to implement *serde's *`Deserialize` trait.
from *serde* libary.
```rust ```rust
# extern crate bytes; # extern crate bytes;
@ -356,14 +355,14 @@ fn main() {
``` ```
[HttpRequest::extract_query()](../actix_web/struct.HttpRequest.html#method.extract_query) [HttpRequest::extract_query()](../actix_web/struct.HttpRequest.html#method.extract_query)
method provides similar functionality for request's query parameters. provides similar functionality for request query parameters.
## Generating resource URLs ## Generating resource URLs
Use the [HttpRequest.url_for()](../actix_web/struct.HttpRequest.html#method.url_for) Use the [HttpRequest.url_for()](../actix_web/struct.HttpRequest.html#method.url_for)
method to generate URLs based on resource patterns. For example, if you've configured a method to generate URLs based on resource patterns. For example, if you've configured a
resource with the name "foo" and the pattern "{a}/{b}/{c}", you might do this. resource with the name "foo" and the pattern "{a}/{b}/{c}", you might do this:
```rust ```rust
# extern crate actix_web; # extern crate actix_web;
@ -387,13 +386,13 @@ fn main() {
This would return something like the string *http://example.com/test/1/2/3* (at least if This would return something like the string *http://example.com/test/1/2/3* (at least if
the current protocol and hostname implied http://example.com). the current protocol and hostname implied http://example.com).
`url_for()` method return [*Url object*](https://docs.rs/url/1.6.0/url/struct.Url.html) so you `url_for()` method returns [*Url object*](https://docs.rs/url/1.6.0/url/struct.Url.html) so you
can modify this url (add query parameters, anchor, etc). can modify this url (add query parameters, anchor, etc).
`url_for()` could be called only for *named* resources otherwise error get returned. `url_for()` could be called only for *named* resources otherwise error get returned.
## External resources ## External resources
Resources that are valid URLs, could be registered as external resources. They are useful Resources that are valid URLs, can be registered as external resources. They are useful
for URL generation purposes only and are never considered for matching at request time. for URL generation purposes only and are never considered for matching at request time.
```rust ```rust
@ -427,8 +426,8 @@ 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 comes without it, it will defined with trailing slash and the request doesn't have one, it will
append it 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.
@ -450,14 +449,14 @@ fn main() {
} }
``` ```
In this example `/resource`, `//resource///` will be redirected to `/resource/` url. In this example `/resource`, `//resource///` will be redirected to `/resource/`.
In this example path normalization handler get registered for all method, In this example 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.
It is possible to register path normalization only for *GET* requests only It is possible to register path normalization only for *GET* requests only:
```rust ```rust
# extern crate actix_web; # extern crate actix_web;
@ -475,9 +474,9 @@ fn main() {
} }
``` ```
## Using a Application Prefix to Compose Applications ## Using an Application Prefix to Compose Applications
The `Application::prefix()`" method allows to set specific application prefix. The `Application::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
@ -509,13 +508,13 @@ it will generate a URL with that same path.
## Custom route predicates ## Custom route predicates
You can think of predicate as simple function that accept *request* object reference You can think of a predicate as a simple function that accepts a *request* object reference
and returns *true* or *false*. Formally predicate is any object that implements and returns *true* or *false*. Formally, a predicate is any object that implements the
[`Predicate`](../actix_web/pred/trait.Predicate.html) trait. Actix provides [`Predicate`](../actix_web/pred/trait.Predicate.html) trait. Actix provides
several predicates, you can check [functions section](../actix_web/pred/index.html#functions) several predicates, you can check [functions section](../actix_web/pred/index.html#functions)
of api docs. of api docs.
Here is simple predicates that check that request contains specific *header*: Here is a simple predicate that check that a request contains a specific *header*:
```rust ```rust
# extern crate actix_web; # extern crate actix_web;
@ -545,9 +544,9 @@ 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 can have access to application's state via `HttpRequest::state()` method. 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
[requests`s extensions](../actix_web/struct.HttpRequest.html#method.extensions). [request extensions](../actix_web/struct.HttpRequest.html#method.extensions).
### Modifying predicate values ### Modifying predicate values
@ -572,14 +571,14 @@ fn main() {
} }
``` ```
`Any` predicate accept list of predicates and matches if any of the supplied The `Any` predicate accepts a list of predicates and matches if any of the supplied
predicates match. i.e: predicates match. i.e:
```rust,ignore ```rust,ignore
pred::Any(pred::Get()).or(pred::Post()) pred::Any(pred::Get()).or(pred::Post())
``` ```
`All` predicate accept list of predicates and matches if all of the supplied The `All` predicate accepts a list of predicates and matches if all of the supplied
predicates match. i.e: predicates match. i.e:
```rust,ignore ```rust,ignore
@ -588,10 +587,10 @@ predicates match. i.e:
## Changing the default Not Found response ## Changing the default Not Found response
If path pattern can not be found in routing table or resource can not find matching If the path pattern can not be found in the routing table or a resource can not find matching
route, default resource is used. Default response is *NOT FOUND* response. route, the default resource is used. The default response is *NOT FOUND*.
It is possible to override *NOT FOUND* response with `Application::default_resource()` method. It is possible to override the *NOT FOUND* response with `Application::default_resource()`.
This method accepts *configuration function* same as normal resource configuration This method accepts a *configuration function* same as normal resource configuration
with `Application::resource()` method. with `Application::resource()` method.
```rust ```rust

View file

@ -2,13 +2,13 @@
## Response ## Response
Builder-like patter is used to construct an instance of `HttpResponse`. A builder-like pattern is used to construct an instance of `HttpResponse`.
`HttpResponse` provides several method that returns `HttpResponseBuilder` instance, `HttpResponse` provides several methods that return a `HttpResponseBuilder` instance,
which is implements various convenience methods that helps build response. which implements various convenience methods that helps building responses.
Check [documentation](../actix_web/dev/struct.HttpResponseBuilder.html) Check [documentation](../actix_web/dev/struct.HttpResponseBuilder.html)
for type description. Methods `.body`, `.finish`, `.json` finalizes response creation and for type descriptions. The methods `.body`, `.finish`, `.json` finalize response creation and
returns constructed *HttpResponse* instance. if this methods get called for the same return a constructed *HttpResponse* instance. If this methods is called for the same
builder instance multiple times, builder will panic. builder instance multiple times, the builder will panic.
```rust ```rust
# extern crate actix_web; # extern crate actix_web;
@ -27,22 +27,22 @@ fn index(req: HttpRequest) -> HttpResponse {
## Content encoding ## Content encoding
Actix automatically *compress*/*decompress* payload. Following codecs are supported: Actix automatically *compresses*/*decompresses* payloads. Following codecs are supported:
* Brotli * Brotli
* Gzip * Gzip
* Deflate * Deflate
* Identity * Identity
If request headers contains `Content-Encoding` header, request payload get decompressed If request headers contain a `Content-Encoding` header, the request payload is decompressed
according to header value. Multiple codecs are not supported, i.e: `Content-Encoding: br, gzip`. according to the header value. Multiple codecs are not supported, i.e: `Content-Encoding: br, gzip`.
Response payload get compressed based on *content_encoding* parameter. Response payload is compressed based on the *content_encoding* parameter.
By default `ContentEncoding::Auto` is used. If `ContentEncoding::Auto` is selected By default `ContentEncoding::Auto` is used. If `ContentEncoding::Auto` is selected
then compression depends on request's `Accept-Encoding` header. then compression depends on the request's `Accept-Encoding` header.
`ContentEncoding::Identity` could be used to disable compression. `ContentEncoding::Identity` can be used to disable compression.
If other content encoding is selected the compression is enforced for this codec. For example, If another content encoding is selected the compression is enforced for this codec. For example,
to enable `brotli` response's body compression use `ContentEncoding::Br`: to enable `brotli` use `ContentEncoding::Br`:
```rust ```rust
# extern crate actix_web; # extern crate actix_web;
@ -60,11 +60,11 @@ fn index(req: HttpRequest) -> HttpResponse {
## JSON Request ## JSON Request
There are two options of json body deserialization. There are two options for json body deserialization.
First option is to use *HttpResponse::json()* method. This method returns The first option is to use *HttpResponse::json()*. This method returns a
[*JsonBody*](../actix_web/dev/struct.JsonBody.html) object which resolves into [*JsonBody*](../actix_web/dev/struct.JsonBody.html) object which resolves into
deserialized value. the deserialized value.
```rust ```rust
# extern crate actix; # extern crate actix;
@ -91,9 +91,9 @@ fn index(mut req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> {
# fn main() {} # fn main() {}
``` ```
Or you can manually load payload into memory and then deserialize it. Or you can manually load the payload into memory and then deserialize it.
Here is simple example. We will deserialize *MyObj* struct. We need to load request Here is a simple example. We will deserialize a *MyObj* struct. We need to load the request
body first and then deserialize json into object. body first and then deserialize the json into an object.
```rust ```rust
# extern crate actix_web; # extern crate actix_web;
@ -124,14 +124,14 @@ fn index(req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> {
# fn main() {} # fn main() {}
``` ```
Complete example for both options is available in A complete example for both options is available in
[examples directory](https://github.com/actix/actix-web/tree/master/examples/json/). [examples directory](https://github.com/actix/actix-web/tree/master/examples/json/).
## JSON Response ## JSON Response
The `Json` type allows you to respond with well-formed JSON data: simply return a value of The `Json` type allows you to respond with well-formed JSON data: simply return a value of
type Json<T> where T is the type of a structure to serialize into *JSON*. The type Json<T> where T is the type of a structure to serialize into *JSON*. The
type `T` must implement the `Serialize` trait from *serde*. type `T` must implement the `Serialize` trait from *serde*.
```rust ```rust
@ -157,14 +157,14 @@ fn main() {
## Chunked transfer encoding ## Chunked transfer encoding
Actix automatically decode *chunked* encoding. `HttpRequest::payload()` already contains Actix automatically decodes *chunked* encoding. `HttpRequest::payload()` already contains
decoded bytes stream. If request payload compressed with one of supported the decoded byte stream. If the request payload is compressed with one of the supported
compression codecs (br, gzip, deflate) bytes stream get decompressed. compression codecs (br, gzip, deflate) the byte stream is decompressed.
Chunked encoding on response could be enabled with `HttpResponseBuilder::chunked()` method. Chunked encoding on response can be enabled with `HttpResponseBuilder::chunked()`.
But this takes effect only for `Body::Streaming(BodyStream)` or `Body::StreamingContext` bodies. But this takes effect only for `Body::Streaming(BodyStream)` or `Body::StreamingContext` bodies.
Also if response payload compression is enabled and streaming body is used, chunked encoding Also if response payload compression is enabled and streaming body is used, chunked encoding
get enabled automatically. is enabled automatically.
Enabling chunked encoding for *HTTP/2.0* responses is forbidden. Enabling chunked encoding for *HTTP/2.0* responses is forbidden.
@ -187,13 +187,13 @@ fn index(req: HttpRequest) -> HttpResponse {
## Multipart body ## Multipart body
Actix provides multipart stream support. Actix provides multipart stream support.
[*Multipart*](../actix_web/multipart/struct.Multipart.html) is implemented as [*Multipart*](../actix_web/multipart/struct.Multipart.html) is implemented as
a stream of multipart items, each item could be a stream of multipart items, each item can be a
[*Field*](../actix_web/multipart/struct.Field.html) or nested *Multipart* stream. [*Field*](../actix_web/multipart/struct.Field.html) or a nested *Multipart* stream.
`HttpResponse::multipart()` method returns *Multipart* stream for current request. `HttpResponse::multipart()` returns the *Multipart* stream for the current request.
In simple form multipart stream handling could be implemented similar to this example In simple form multipart stream handling can be implemented similar to this example
```rust,ignore ```rust,ignore
# extern crate actix_web; # extern crate actix_web;
@ -206,7 +206,7 @@ fn index(req: HttpRequest) -> Box<Future<...>> {
// Handle multipart Field // Handle multipart Field
multipart::MultipartItem::Field(field) => { multipart::MultipartItem::Field(field) => {
println!("==== FIELD ==== {:?} {:?}", field.headers(), field.content_type()); println!("==== FIELD ==== {:?} {:?}", field.headers(), field.content_type());
Either::A( Either::A(
// Field in turn is a stream of *Bytes* objects // Field in turn is a stream of *Bytes* objects
field.map(|chunk| { field.map(|chunk| {
@ -215,7 +215,7 @@ fn index(req: HttpRequest) -> Box<Future<...>> {
.fold((), |_, _| result(Ok(())))) .fold((), |_, _| result(Ok(()))))
}, },
multipart::MultipartItem::Nested(mp) => { multipart::MultipartItem::Nested(mp) => {
// Or item could be nested Multipart stream // Or item could be nested Multipart stream
Either::B(result(Ok(()))) Either::B(result(Ok(())))
} }
} }
@ -223,16 +223,16 @@ fn index(req: HttpRequest) -> Box<Future<...>> {
} }
``` ```
Full example is available in A full example is available in the
[examples directory](https://github.com/actix/actix-web/tree/master/examples/multipart/). [examples directory](https://github.com/actix/actix-web/tree/master/examples/multipart/).
## Urlencoded body ## Urlencoded body
Actix provides support for *application/x-www-form-urlencoded* encoded body. Actix provides support for *application/x-www-form-urlencoded* encoded bodies.
`HttpResponse::urlencoded()` method returns `HttpResponse::urlencoded()` returns a
[*UrlEncoded*](../actix_web/dev/struct.UrlEncoded.html) future, it resolves [*UrlEncoded*](../actix_web/dev/struct.UrlEncoded.html) future, which resolves
into `HashMap<String, String>` which contains decoded parameters. into `HashMap<String, String>` which contains decoded parameters.
*UrlEncoded* future can resolve into a error in several cases: The *UrlEncoded* future can resolve into a error in several cases:
* content type is not `application/x-www-form-urlencoded` * content type is not `application/x-www-form-urlencoded`
* transfer encoding is `chunked`. * transfer encoding is `chunked`.
@ -261,10 +261,10 @@ fn index(mut req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> {
## Streaming request ## Streaming request
*HttpRequest* is a stream of `Bytes` objects. It could be used to read request *HttpRequest* is a stream of `Bytes` objects. It can be used to read the request
body payload. body payload.
In this example handle reads request payload chunk by chunk and prints every chunk. In this example handle reads the request payload chunk by chunk and prints every chunk.
```rust ```rust
# extern crate actix_web; # extern crate actix_web;

View file

@ -1,14 +1,14 @@
# Testing # Testing
Every application should be well tested and. Actix provides the tools to perform unit and Every application should be well tested. Actix provides tools to perform unit and
integration tests. integration tests.
## Unit tests ## Unit tests
For unit testing actix provides request builder type and simple handler runner. For unit testing actix provides a request builder type and simple handler runner.
[*TestRequest*](../actix_web/test/struct.TestRequest.html) implements builder-like pattern. [*TestRequest*](../actix_web/test/struct.TestRequest.html) implements a builder-like pattern.
You can generate `HttpRequest` instance with `finish()` method or you can You can generate a `HttpRequest` instance with `finish()` or you can
run your handler with `run()` or `run_async()` methods. run your handler with `run()` or `run_async()`.
```rust ```rust
# extern crate http; # extern crate http;
@ -42,15 +42,15 @@ fn main() {
## Integration tests ## Integration tests
There are several methods how you can test your application. Actix provides There are several methods how you can test your application. Actix provides
[*TestServer*](../actix_web/test/struct.TestServer.html) [*TestServer*](../actix_web/test/struct.TestServer.html)
server that could be used to run whole application of just specific handlers server that can be used to run the whole application of just specific handlers
in real http server. *TrstServer::get()*, *TrstServer::post()* or *TrstServer::client()* in real http server. *TestServer::get()*, *TestServer::post()* or *TestServer::client()*
methods could be used to send request to test server. methods can be used to send requests to the test server.
In simple form *TestServer* could be configured to use handler. *TestServer::new* method In simple form *TestServer* can be configured to use handler. *TestServer::new* method
accepts configuration function, only argument for this function is *test application* accepts configuration function, only argument for this function is *test application*
instance. You can check [api documentation](../actix_web/test/struct.TestApp.html) instance. You can check the [api documentation](../actix_web/test/struct.TestApp.html)
for more information. for more information.
```rust ```rust
@ -73,8 +73,8 @@ fn main() {
} }
``` ```
Other option is to use application factory. In this case you need to pass factory function The other option is to use an application factory. In this case you need to pass the factory
same as you use for real http server configuration. function same way as you would for real http server configuration.
```rust ```rust
# extern crate http; # extern crate http;
@ -105,13 +105,13 @@ fn main() {
## WebSocket server tests ## WebSocket server tests
It is possible to register *handler* with `TestApp::handler()` method that It is possible to register a *handler* with `TestApp::handler()` that
initiate web socket connection. *TestServer* provides `ws()` which connects to initiates a web socket connection. *TestServer* provides `ws()` which connects to
websocket server and returns ws reader and writer objects. *TestServer* also the websocket server and returns ws reader and writer objects. *TestServer* also
provides `execute()` method which runs future object to completion and returns provides an `execute()` method which runs future objects to completion and returns
result of the future computation. result of the future computation.
Here is simple example, that shows how to test server websocket handler. Here is a simple example that shows how to test server websocket handler.
```rust ```rust
# extern crate actix; # extern crate actix;
@ -147,7 +147,7 @@ fn main() {
let (reader, mut writer) = srv.ws().unwrap(); // <- connect to ws server let (reader, mut writer) = srv.ws().unwrap(); // <- connect to ws server
writer.text("text"); // <- send message to server writer.text("text"); // <- send message to server
let (item, reader) = srv.execute(reader.into_future()).unwrap(); // <- wait for one message let (item, reader) = srv.execute(reader.into_future()).unwrap(); // <- wait for one message
assert_eq!(item, Some(ws::Message::Text("text".to_owned()))); assert_eq!(item, Some(ws::Message::Text("text".to_owned())));
} }

View file

@ -1,12 +1,12 @@
# WebSockets # WebSockets
Actix supports WebSockets out-of-the-box. It is possible to convert request's `Payload` Actix supports WebSockets out-of-the-box. It is possible to convert a request's `Payload`
to a stream of [*ws::Message*](../actix_web/ws/enum.Message.html) with to a stream of [*ws::Message*](../actix_web/ws/enum.Message.html) with
a [*ws::WsStream*](../actix_web/ws/struct.WsStream.html) and then use stream a [*ws::WsStream*](../actix_web/ws/struct.WsStream.html) and then use stream
combinators to handle actual messages. But it is simpler to handle websocket communications combinators to handle actual messages. But it is simpler to handle websocket communications
with http actor. with an http actor.
This is example of simple websocket echo server: This is example of a simple websocket echo server:
```rust ```rust
# extern crate actix; # extern crate actix;
@ -41,8 +41,8 @@ fn main() {
} }
``` ```
Simple websocket echo server example is available in A simple websocket echo server example is available in the
[examples directory](https://github.com/actix/actix-web/blob/master/examples/websocket). [examples directory](https://github.com/actix/actix-web/blob/master/examples/websocket).
Example chat server with ability to chat over websocket connection or tcp connection An example chat server with the ability to chat over a websocket or tcp connection
is available in [websocket-chat directory](https://github.com/actix/actix-web/tree/master/examples/websocket-chat/) is available in [websocket-chat directory](https://github.com/actix/actix-web/tree/master/examples/websocket-chat/)