mirror of
https://github.com/fafhrd91/actix-web
synced 2024-11-24 08:22:59 +01:00
Merge pull request #138 from bwasty/guide
Guide: improve wording & style
This commit is contained in:
commit
80f6b93714
@ -1,6 +1,6 @@
|
||||
# Quick start
|
||||
|
||||
Before you can start writing a actix web application, you’ll need a version of Rust installed.
|
||||
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
|
||||
|
@ -1,23 +1,23 @@
|
||||
# Middlewares
|
||||
# Middleware
|
||||
|
||||
Actix middlewares system allows to add additional behavior to request/response processing.
|
||||
Middleware can hook into incoming request process and modify request or halt request
|
||||
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
|
||||
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
|
||||
* Post-process a Response
|
||||
* Modify application state
|
||||
* Access external services (redis, logging, sessions)
|
||||
|
||||
Middlewares are registered for each application and get executed in same order as
|
||||
registration order. In general, *middleware* is a type that implements
|
||||
Middlewares are registered for each application and are executed in same order as
|
||||
registration order. In general, a *middleware* is a type that implements the
|
||||
[*Middleware trait*](../actix_web/middlewares/trait.Middleware.html). Each method
|
||||
in this trait has default implementation. Each method can return result immediately
|
||||
or *future* object.
|
||||
in this trait has a default implementation. Each method can return a result immediately
|
||||
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
|
||||
# extern crate http;
|
||||
@ -52,26 +52,26 @@ impl<S> Middleware<S> for Headers {
|
||||
|
||||
fn main() {
|
||||
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));
|
||||
}
|
||||
```
|
||||
|
||||
Active provides several useful middlewares, like *logging*, *user sessions*, etc.
|
||||
Actix provides several useful middlewares, like *logging*, *user sessions*, etc.
|
||||
|
||||
|
||||
## Logging
|
||||
|
||||
Logging is implemented as middleware.
|
||||
It is common to register logging middleware as first middleware for application.
|
||||
Logging is implemented as a middleware.
|
||||
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
|
||||
uses 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)
|
||||
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).
|
||||
|
||||
### Usage
|
||||
|
||||
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
|
||||
%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
|
||||
@ -129,9 +129,9 @@ INFO:actix_web::middleware::logger: 127.0.0.1:59947 [02/Dec/2017:00:22:40 -0800]
|
||||
|
||||
## Default headers
|
||||
|
||||
To set default response headers `DefaultHeaders` middleware could be used.
|
||||
*DefaultHeaders* middleware does not set header if response headers already contains
|
||||
specified header.
|
||||
To set default response headers the `DefaultHeaders` middleware can be used. The
|
||||
*DefaultHeaders* middleware does not set the header if response headers already contain
|
||||
the specified header.
|
||||
|
||||
```rust
|
||||
# extern crate actix_web;
|
||||
@ -153,16 +153,16 @@ fn main() {
|
||||
|
||||
## User sessions
|
||||
|
||||
Actix provides general solution for session management.
|
||||
[*Session storage*](../actix_web/middleware/struct.SessionStorage.html) middleware can be
|
||||
use with different backend types to store session data in different backends.
|
||||
By default only cookie session backend is implemented. Other backend implementations
|
||||
Actix provides a general solution for session management. The
|
||||
[*Session storage*](../actix_web/middleware/struct.SessionStorage.html) middleware can be
|
||||
used with different backend types to store session data in different backends.
|
||||
By default only cookie session backend is implemented. Other backend implementations
|
||||
could be added later.
|
||||
|
||||
[*Cookie session backend*](../actix_web/middleware/struct.CookieSessionBackend.html)
|
||||
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
|
||||
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*.
|
||||
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*.
|
||||
To access session data
|
||||
[*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 data.
|
||||
|
||||
|
@ -24,9 +24,9 @@ fn main() {
|
||||
|
||||
## 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
|
||||
it won't be able to server sub-paths.
|
||||
it won't be able to serve sub-paths.
|
||||
|
||||
```rust
|
||||
# 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.
|
||||
|
||||
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)
|
||||
method to configure this redirect.
|
||||
|
@ -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
|
||||
[tls alpn](https://tools.ietf.org/html/rfc7301). At the moment only
|
||||
`rust-openssl` has support. Turn on `alpn` feature to enable `alpn` negotiation.
|
||||
With enable `alpn` feature `HttpServer` provides
|
||||
`rust-openssl` has support. Turn on the `alpn` feature to enable `alpn` negotiation.
|
||||
With enabled `alpn` feature `HttpServer` provides the
|
||||
[serve_tls](../actix_web/struct.HttpServer.html#method.serve_tls) method.
|
||||
|
||||
```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
|
||||
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)
|
||||
for concrete example.
|
||||
Please check [example](https://github.com/actix/actix-web/tree/master/examples/tls)
|
||||
for a concrete example.
|
||||
|
@ -3,13 +3,13 @@
|
||||
## Diesel
|
||||
|
||||
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
|
||||
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.
|
||||
We have to define sync actor and connection that this actor will use. Same approach
|
||||
could be used for other databases.
|
||||
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. The same approach
|
||||
can be used for other databases.
|
||||
|
||||
```rust,ignore
|
||||
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
|
||||
struct CreateUser {
|
||||
@ -33,8 +33,8 @@ impl Message for CreateUser {
|
||||
}
|
||||
```
|
||||
|
||||
We can send `CreateUser` message to `DbExecutor` actor, and as result we get
|
||||
`User` model. Now we need to define actual handler implementation for this message.
|
||||
We can send a `CreateUser` message to the `DbExecutor` actor, and as a result we get a
|
||||
`User` model instance. Now we need to define the actual handler implementation for this message.
|
||||
|
||||
```rust,ignore
|
||||
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.
|
||||
All we need is to start *DbExecutor* actors and store address in a state where http handler
|
||||
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 the address in a state where http handler
|
||||
can access it.
|
||||
|
||||
```rust,ignore
|
||||
@ -97,8 +97,8 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
And finally we can use address in a request handler. We get message response
|
||||
asynchronously, so handler needs to return future object, also `Route::a()` needs to be
|
||||
And finally we can use the address in a request handler. We get a message response
|
||||
asynchronously, so the handler needs to return a future object, also `Route::a()` needs to be
|
||||
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/).
|
||||
|
||||
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).
|
||||
|
@ -3,9 +3,9 @@
|
||||
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 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!
|
||||
|
||||
Let’s write our first actix web application! Start by creating a new binary-based
|
||||
Cargo project and changing into the new directory:
|
||||
@ -15,7 +15,7 @@ cargo new hello-world --bin
|
||||
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:
|
||||
|
||||
```toml
|
||||
@ -26,7 +26,7 @@ actix-web = "0.4"
|
||||
|
||||
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`:
|
||||
|
||||
```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
|
||||
connections. Server accepts function that should return `HttpHandler` instance:
|
||||
After that, the application instance can be used with `HttpServer` to listen for incoming
|
||||
connections. The server accepts a function that should return an `HttpHandler` instance:
|
||||
|
||||
```rust,ignore
|
||||
HttpServer::new(
|
||||
@ -64,7 +64,7 @@ connections. Server accepts function that should return `HttpHandler` instance:
|
||||
.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:
|
||||
@ -92,7 +92,7 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
Note on `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
|
||||
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 a
|
||||
properly configured actix system. For more information please check
|
||||
[actix documentation](https://actix.github.io/actix/actix/)
|
||||
|
@ -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,
|
||||
websocket protocol handling, multipart streams, etc.
|
||||
|
||||
All actix web server is built around `Application` instance.
|
||||
It is used for registering routes for resources, middlewares.
|
||||
Also it stores application specific state that is shared across all handlers
|
||||
All actix web servers are built around the `Application` 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.
|
||||
|
||||
Application acts as namespace for all routes, i.e all routes for specific application
|
||||
has same url path prefix. Application prefix always contains leading "/" slash.
|
||||
If supplied prefix does not contain leading slash, it get inserted.
|
||||
Prefix should consists of value path segments. i.e for application with prefix `/app`
|
||||
any request with following paths `/app`, `/app/` or `/app/test` would match,
|
||||
Application acts 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.
|
||||
|
||||
```rust,ignore
|
||||
@ -32,11 +32,11 @@ but path `/application` would not match.
|
||||
```
|
||||
|
||||
In this example application with `/app` prefix and `index.html` resource
|
||||
get created. This resource is available as on `/app/index.html` url.
|
||||
For more information check
|
||||
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.
|
||||
|
||||
Multiple applications could be served with one server:
|
||||
Multiple applications can be served with one server:
|
||||
|
||||
```rust
|
||||
# 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.
|
||||
Applications get matched based on registration order, if application with more general
|
||||
prefix is registered before less generic, that would effectively block less generic
|
||||
application to get matched. For example if *application* with prefix "/" get registered
|
||||
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.
|
||||
|
||||
## State
|
||||
|
||||
Application state is shared with all routes and resources within same application.
|
||||
State could be accessed with `HttpRequest::state()` method as a read-only item
|
||||
but interior mutability pattern with `RefCell` could be used to archive state mutability.
|
||||
State could be accessed with `HttpContext::state()` in case of http actor.
|
||||
State also available to route matching predicates and middlewares.
|
||||
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.
|
||||
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:
|
||||
|
||||
```rust
|
||||
@ -102,8 +102,8 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
Note on application state, http server accepts application factory rather than application
|
||||
instance. Http server construct application instance for each thread, so application state
|
||||
must be constructed multiple times. If you want to share state between different thread
|
||||
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 application factory must be `Send` + `Sync`.
|
||||
but the application factory must be `Send` + `Sync`.
|
||||
|
@ -1,13 +1,13 @@
|
||||
# Server
|
||||
|
||||
[*HttpServer*](../actix_web/struct.HttpServer.html) type is responsible for
|
||||
serving http requests. *HttpServer* accept application factory as a parameter,
|
||||
Application factory must have `Send` + `Sync` boundaries. More about that in
|
||||
*multi-threading* section. To bind to specific socket address `bind()` must be used.
|
||||
This method could be called multiple times. To start http server one of the *start*
|
||||
methods could be used. `start()` method start simple server, `start_tls()` or `start_ssl()`
|
||||
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 properly configured actix system:
|
||||
within a properly configured actix system:
|
||||
|
||||
```rust
|
||||
# extern crate actix;
|
||||
@ -29,13 +29,13 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
It is possible to start server in separate thread with *spawn()* method. In that
|
||||
case server spawns new thread and create new actix system in it. To stop
|
||||
this server send `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 server
|
||||
via messaging system. All start methods like `start()`, `start_ssl()`, etc returns
|
||||
address of the started http server. Actix http server accept several messages:
|
||||
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:
|
||||
|
||||
* `PauseServer` - Pause accepting incoming connections
|
||||
* `ResumeServer` - Resume accepting incoming connections
|
||||
@ -73,9 +73,9 @@ fn main() {
|
||||
|
||||
## Multi-threading
|
||||
|
||||
Http server automatically starts number of http workers, by default
|
||||
this number is equal to number of logical cpu in the system. This number
|
||||
could be overridden with `HttpServer::threads()` method.
|
||||
Http server 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.
|
||||
|
||||
```rust
|
||||
# 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
|
||||
does not need to be `Send` and `Sync` but application factory must be `Send` + `Sync`.
|
||||
|
||||
## 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`.
|
||||
|
||||
```toml
|
||||
@ -127,7 +127,7 @@ Note on *HTTP/2.0* protocol over tls without prior knowledge, it requires
|
||||
`openssl` has `alpn ` support.
|
||||
|
||||
Please check [example](https://github.com/actix/actix-web/tree/master/examples/tls)
|
||||
for full example.
|
||||
for a full example.
|
||||
|
||||
## Keep-Alive
|
||||
|
||||
@ -162,13 +162,13 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
If first option is selected then *keep alive* state
|
||||
calculated based on response's *connection-type*. By default
|
||||
If 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*.
|
||||
|
||||
*Connection type* could be change with `HttpResponseBuilder::connection_type()` method.
|
||||
*Connection type* can be change with `HttpResponseBuilder::connection_type()` method.
|
||||
|
||||
```rust
|
||||
# extern crate actix_web;
|
||||
@ -186,13 +186,13 @@ fn index(req: HttpRequest) -> HttpResponse {
|
||||
|
||||
## Graceful shutdown
|
||||
|
||||
Actix http server support graceful shutdown. After receiving a stop signal, workers
|
||||
have 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.
|
||||
You can change this parameter with `HttpServer::shutdown_timeout()` method.
|
||||
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
|
||||
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 stop message to server with server address and specify if you what
|
||||
graceful shutdown or not. `start()` methods return address of the server.
|
||||
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.
|
||||
|
||||
Http server handles several OS signals. *CTRL-C* is available on all OSs,
|
||||
other signals are available on unix systems.
|
||||
@ -201,4 +201,4 @@ other signals are available on unix systems.
|
||||
* *SIGTERM* - Graceful 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.
|
||||
|
@ -1,16 +1,16 @@
|
||||
# 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).
|
||||
Request handling happen in two stages. First handler object get called.
|
||||
Handle can return any object that implements
|
||||
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()` get called on returned object. And finally
|
||||
result of the `respond_to()` call get converted to `Reply` object.
|
||||
Then `respond_to()` is called on the returned object. And finally
|
||||
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.
|
||||
For complete list of implementations check
|
||||
For a complete list of implementations, check
|
||||
[*Responder documentation*](../actix_web/trait.Responder.html#foreign-impls).
|
||||
|
||||
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
|
||||
*Handler* trait is generic over *S*, which defines application state type. So
|
||||
application state is accessible from handler with `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 mutable access it's own state
|
||||
as `handle` method takes mutable reference to *self*. Beware, actix creates multiple copies
|
||||
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 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.
|
||||
|
||||
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
|
||||
# extern crate actix;
|
||||
@ -71,8 +71,8 @@ impl<S> Handler<S> for MyHandler {
|
||||
# fn main() {}
|
||||
```
|
||||
|
||||
This handler will work, but `self.0` value will be different depends on number of threads and
|
||||
number of requests processed per thread. Proper implementation would use `Arc` and `AtomicUsize`
|
||||
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`
|
||||
|
||||
```rust
|
||||
# extern crate actix;
|
||||
@ -100,7 +100,7 @@ fn main() {
|
||||
let inc = Arc::new(AtomicUsize::new(0));
|
||||
|
||||
HttpServer::new(
|
||||
move || {
|
||||
move || {
|
||||
let cloned = inc.clone();
|
||||
Application::new()
|
||||
.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
|
||||
handles request 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 [actix](https://actix.github.io/actix/actix/) actor system.
|
||||
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 custom type directly from handler function, type needs to implement `Responder` trait.
|
||||
Let's create response for custom type that serializes to `application/json` response:
|
||||
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
|
||||
# extern crate actix;
|
||||
@ -174,11 +174,10 @@ fn main() {
|
||||
|
||||
## 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
|
||||
that implements [*Responder*](../actix_web/trait.Responder.html) trait. In this case handle must
|
||||
return `Future` object that resolves to *Responder* type, i.e:
|
||||
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:
|
||||
|
||||
```rust
|
||||
# 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:
|
||||
|
||||
```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`.
|
||||
In this example `index` handler can return error immediately or return
|
||||
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
|
||||
future that resolves to a `HttpResponse`.
|
||||
|
||||
```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
|
||||
you can do error check and return error and return async response otherwise.
|
||||
Or any result that requires two different types.
|
||||
For this case [*Either*](../actix_web/enum.Either.html) type can be used.
|
||||
*Either* allows to combine two different responder types into a single type.
|
||||
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;
|
||||
@ -308,9 +307,9 @@ fn index(req: HttpRequest) -> RegisterResult {
|
||||
|
||||
## 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)
|
||||
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)
|
||||
method.
|
||||
|
@ -1,20 +1,20 @@
|
||||
# Errors
|
||||
|
||||
Actix uses [`Error` type](../actix_web/error/struct.Error.html)
|
||||
and [`ResponseError` trait](../actix_web/error/trait.ResponseError.html)
|
||||
Actix uses [`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 `ResponseError` trait can be returned as error value.
|
||||
*Handler* can return *Result* object, actix by default provides
|
||||
`Responder` implementation for compatible result types. Here is implementation
|
||||
Any error that implements the `ResponseError` trait can be returned as an error value.
|
||||
*Handler* can return an *Result* object; actix by default provides
|
||||
`Responder` implementation for compatible result types. Here is the implementation
|
||||
definition:
|
||||
|
||||
```rust,ignore
|
||||
impl<T: Responder, E: Into<Error>> Responder for Result<T, E>
|
||||
```
|
||||
|
||||
And any error that implements `ResponseError` can be converted into `Error` object.
|
||||
For example if *handler* function returns `io::Error`, it would be converted
|
||||
into `HttpInternalServerError` response. Implementation for `io::Error` is provided
|
||||
And 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.
|
||||
|
||||
```rust
|
||||
@ -35,9 +35,9 @@ 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 `ResponseError` trait
|
||||
for custom error. `ResponseError` trait has default implementation
|
||||
for `error_response()` method, it generates *500* response.
|
||||
To add support for custom errors, all we need to do is just 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.
|
||||
|
||||
```rust
|
||||
# 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
|
||||
to return different responses for different type of errors.
|
||||
In this example the *index* handler always returns a *500* response. But it is easy
|
||||
to return different responses for different types of errors.
|
||||
|
||||
```rust
|
||||
# extern crate actix_web;
|
||||
@ -108,7 +108,7 @@ fn index(req: HttpRequest) -> Result<&'static str, MyError> {
|
||||
|
||||
## 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.
|
||||
|
||||
```rust
|
||||
@ -123,7 +123,7 @@ struct MyError {
|
||||
|
||||
fn index(req: HttpRequest) -> Result<&'static str> {
|
||||
let result: Result<&'static str, MyError> = Err(MyError{name: "test"});
|
||||
|
||||
|
||||
Ok(result.map_err(|e| error::ErrorBadRequest(e))?)
|
||||
}
|
||||
# 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
|
||||
|
||||
Actix logs all errors with `WARN` log level. If log level set to `DEBUG`
|
||||
and `RUST_BACKTRACE` is enabled, backtrace get logged. The Error type uses
|
||||
cause's error backtrace if available, if the underlying failure does not provide
|
||||
Actix logs all errors with the log level `WARN`. If log level set to `DEBUG`
|
||||
and `RUST_BACKTRACE` is enabled, the backtrace gets logged. The Error type uses
|
||||
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
|
||||
(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
|
||||
|
@ -1,23 +1,23 @@
|
||||
# URL Dispatch
|
||||
|
||||
URL dispatch provides a simple way to map 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
|
||||
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 [handler section](../qs_4.html).
|
||||
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 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.
|
||||
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 *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*).
|
||||
|
||||
The [Application::resource](../actix_web/struct.Application.html#method.resource) methods
|
||||
add a single resource to application routing table. This method accepts *path pattern*
|
||||
and resource configuration function.
|
||||
add a single resource to application routing table. This method accepts a *path pattern*
|
||||
and a resource configuration function.
|
||||
|
||||
```rust
|
||||
# extern crate actix_web;
|
||||
@ -37,26 +37,26 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
*Configuration function* has following type:
|
||||
The *Configuration function* has the following type:
|
||||
|
||||
```rust,ignore
|
||||
FnOnce(&mut Resource<_>) -> ()
|
||||
```
|
||||
|
||||
*Configuration function* can set name and register specific routes.
|
||||
If resource does not contain any route or does not have any matching routes it
|
||||
returns *NOT FOUND* http resources.
|
||||
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
|
||||
returns *NOT FOUND* http response.
|
||||
|
||||
## Configuring a Route
|
||||
|
||||
Resource contains set of routes. Each route in turn has set of predicates and handler.
|
||||
New route could be created with `Resource::route()` method which returns reference
|
||||
to new *Route* instance. By default *route* does not contain any predicates, so matches
|
||||
all requests and default handler is `HttpNotFound`.
|
||||
Resource contains a set of routes. Each route in turn has a set of predicates and a handler.
|
||||
New routes can be created with `Resource::route()` method which returns a reference
|
||||
to new *Route* instance. By default the *route* does not contain any predicates, so matches
|
||||
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
|
||||
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.
|
||||
|
||||
```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*
|
||||
and path equals to `/test`. Resource calls handle of the first matches route.
|
||||
If resource can not match any route "NOT FOUND" response get returned.
|
||||
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) method returns
|
||||
[*Route*](../actix_web/struct.Route.html) object. Route can be configured with
|
||||
[*Resource::route()*](../actix_web/struct.Resource.html#method.route) returns a
|
||||
[*Route*](../actix_web/struct.Route.html) object. Route can be configured with a
|
||||
builder-like pattern. Following configuration methods are available:
|
||||
|
||||
* [*Route::filter()*](../actix_web/struct.Route.html#method.filter) method registers new predicate,
|
||||
any number of predicates could be registered for each route.
|
||||
* [*Route::filter()*](../actix_web/struct.Route.html#method.filter) registers a new predicate.
|
||||
Any number of predicates can be registered for each route.
|
||||
|
||||
* [*Route::f()*](../actix_web/struct.Route.html#method.f) method registers handler function
|
||||
for this route. Only one handler could be registered. Usually handler registration
|
||||
is the last config operation. Handler function could be function or closure and has type
|
||||
* [*Route::f()*](../actix_web/struct.Route.html#method.f) registers handler function
|
||||
for this route. Only one handler can be registered. Usually handler registration
|
||||
is the last config operation. Handler function can be a function or closure and has the type
|
||||
`Fn(HttpRequest<S>) -> R + 'static`
|
||||
|
||||
* [*Route::h()*](../actix_web/struct.Route.html#method.h) method registers handler object
|
||||
that implements `Handler` trait. This is similar to `f()` method, only one handler could
|
||||
* [*Route::h()*](../actix_web/struct.Route.html#method.h) registers a handler object
|
||||
that implements the `Handler` trait. This is similar to `f()` method - only one handler can
|
||||
be registered. Handler registration is the last config operation.
|
||||
|
||||
* [*Route::a()*](../actix_web/struct.Route.html#method.a) method registers async handler
|
||||
function for this route. Only one handler could be registered. Handler registration
|
||||
is the last config operation. Handler function could be function or closure and has type
|
||||
* [*Route::a()*](../actix_web/struct.Route.html#method.a) registers an async handler
|
||||
function for this route. Only one handler can be registered. Handler registration
|
||||
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`
|
||||
|
||||
## 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,
|
||||
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 routes were declared via `Application::resource()` method. If resource could not be found,
|
||||
*default resource* get used as matched resource.
|
||||
the routes were declared via `Application::resource()` method. If resource can not be found,
|
||||
the *default resource* is used as the matched resource.
|
||||
|
||||
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
|
||||
@ -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.
|
||||
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
[`HttpRequest::match_info`](../actix_web/struct.HttpRequest.html#method.match_info).
|
||||
Specific value can be received with
|
||||
[`Params::get()`](../actix_web/dev/struct.Params.html#method.get) method.
|
||||
Specific values can be retrieved with
|
||||
[`Params::get()`](../actix_web/dev/struct.Params.html#method.get).
|
||||
|
||||
Any matched parameter can be deserialized into specific type if this type
|
||||
implements `FromParam` trait. For example most of standard integer types
|
||||
implements `FromParam` trait. i.e.:
|
||||
Any matched parameter can be deserialized into a specific type if the type
|
||||
implements the `FromParam` trait. For example most standard integer types
|
||||
the trait, i.e.:
|
||||
|
||||
```rust
|
||||
# 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)
|
||||
|
||||
## 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.
|
||||
[HttpRequest::extract_path()](../actix_web/struct.HttpRequest.html#method.extract_path)
|
||||
method extracts information, destination type has to implements `Deserialize` trait
|
||||
from *serde* libary.
|
||||
extracts information, the destination type has to implement *serde's *`Deserialize` trait.
|
||||
|
||||
```rust
|
||||
# extern crate bytes;
|
||||
@ -356,14 +355,14 @@ fn main() {
|
||||
```
|
||||
|
||||
[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
|
||||
|
||||
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
|
||||
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
|
||||
# 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
|
||||
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).
|
||||
`url_for()` could be called only for *named* resources otherwise error get returned.
|
||||
|
||||
## 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.
|
||||
|
||||
```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.
|
||||
|
||||
If *append* is *true* append slash when needed. If a resource is
|
||||
defined with trailing slash and the request comes without it, it will
|
||||
append it automatically.
|
||||
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.
|
||||
|
||||
@ -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
|
||||
slash-appending *Not Found* will turn a *POST* request into a GET, losing any
|
||||
*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
|
||||
# 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
|
||||
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
|
||||
@ -509,13 +508,13 @@ it will generate a URL with that same path.
|
||||
|
||||
## Custom route predicates
|
||||
|
||||
You can think of predicate as simple function that accept *request* object reference
|
||||
and returns *true* or *false*. Formally predicate is any object that implements
|
||||
You can think of a predicate as a simple function that accepts a *request* object reference
|
||||
and returns *true* or *false*. Formally, a predicate is any object that implements the
|
||||
[`Predicate`](../actix_web/pred/trait.Predicate.html) trait. Actix provides
|
||||
several predicates, you can check [functions section](../actix_web/pred/index.html#functions)
|
||||
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
|
||||
# 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.
|
||||
|
||||
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
|
||||
[requests`s extensions](../actix_web/struct.HttpRequest.html#method.extensions).
|
||||
[request extensions](../actix_web/struct.HttpRequest.html#method.extensions).
|
||||
|
||||
### 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:
|
||||
|
||||
```rust,ignore
|
||||
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:
|
||||
|
||||
```rust,ignore
|
||||
@ -588,10 +587,10 @@ predicates match. i.e:
|
||||
|
||||
## Changing the default Not Found response
|
||||
|
||||
If path pattern can not be found in routing table or resource can not find matching
|
||||
route, default resource is used. Default response is *NOT FOUND* response.
|
||||
It is possible to override *NOT FOUND* response with `Application::default_resource()` method.
|
||||
This method accepts *configuration function* same as normal resource configuration
|
||||
If the path pattern can not be found in the routing table or a resource can not find matching
|
||||
route, the default resource is used. The default response is *NOT FOUND*.
|
||||
It is possible to override the *NOT FOUND* response with `Application::default_resource()`.
|
||||
This method accepts a *configuration function* same as normal resource configuration
|
||||
with `Application::resource()` method.
|
||||
|
||||
```rust
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
## Response
|
||||
|
||||
Builder-like patter is used to construct an instance of `HttpResponse`.
|
||||
`HttpResponse` provides several method that returns `HttpResponseBuilder` instance,
|
||||
which is implements various convenience methods that helps build response.
|
||||
A builder-like pattern is used to construct an instance of `HttpResponse`.
|
||||
`HttpResponse` provides several methods that return a `HttpResponseBuilder` instance,
|
||||
which implements various convenience methods that helps building responses.
|
||||
Check [documentation](../actix_web/dev/struct.HttpResponseBuilder.html)
|
||||
for type description. Methods `.body`, `.finish`, `.json` finalizes response creation and
|
||||
returns constructed *HttpResponse* instance. if this methods get called for the same
|
||||
builder instance multiple times, builder will panic.
|
||||
for type descriptions. The methods `.body`, `.finish`, `.json` finalize response creation and
|
||||
return a constructed *HttpResponse* instance. If this methods is called for the same
|
||||
builder instance multiple times, the builder will panic.
|
||||
|
||||
```rust
|
||||
# extern crate actix_web;
|
||||
@ -27,22 +27,22 @@ fn index(req: HttpRequest) -> HttpResponse {
|
||||
|
||||
## Content encoding
|
||||
|
||||
Actix automatically *compress*/*decompress* payload. Following codecs are supported:
|
||||
Actix automatically *compresses*/*decompresses* payloads. Following codecs are supported:
|
||||
|
||||
* Brotli
|
||||
* Gzip
|
||||
* Deflate
|
||||
* Identity
|
||||
|
||||
If request headers contains `Content-Encoding` header, request payload get decompressed
|
||||
according to header value. Multiple codecs are not supported, i.e: `Content-Encoding: br, gzip`.
|
||||
|
||||
Response payload get compressed based on *content_encoding* parameter.
|
||||
|
||||
If request headers contain a `Content-Encoding` header, the request payload is decompressed
|
||||
according to the header value. Multiple codecs are not supported, i.e: `Content-Encoding: br, gzip`.
|
||||
|
||||
Response payload is compressed based on the *content_encoding* parameter.
|
||||
By default `ContentEncoding::Auto` is used. If `ContentEncoding::Auto` is selected
|
||||
then compression depends on request's `Accept-Encoding` header.
|
||||
`ContentEncoding::Identity` could be used to disable compression.
|
||||
If other content encoding is selected the compression is enforced for this codec. For example,
|
||||
to enable `brotli` response's body compression use `ContentEncoding::Br`:
|
||||
then compression depends on the request's `Accept-Encoding` header.
|
||||
`ContentEncoding::Identity` can be used to disable compression.
|
||||
If another content encoding is selected the compression is enforced for this codec. For example,
|
||||
to enable `brotli` use `ContentEncoding::Br`:
|
||||
|
||||
```rust
|
||||
# extern crate actix_web;
|
||||
@ -60,11 +60,11 @@ fn index(req: HttpRequest) -> HttpResponse {
|
||||
|
||||
## 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
|
||||
[*JsonBody*](../actix_web/dev/struct.JsonBody.html) object which resolves into
|
||||
deserialized value.
|
||||
The first option is to use *HttpResponse::json()*. This method returns a
|
||||
[*JsonBody*](../actix_web/dev/struct.JsonBody.html) object which resolves into
|
||||
the deserialized value.
|
||||
|
||||
```rust
|
||||
# extern crate actix;
|
||||
@ -91,9 +91,9 @@ fn index(mut req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> {
|
||||
# fn main() {}
|
||||
```
|
||||
|
||||
Or you can manually load payload into memory and then deserialize it.
|
||||
Here is simple example. We will deserialize *MyObj* struct. We need to load request
|
||||
body first and then deserialize json into object.
|
||||
Or you can manually load the payload into memory and then deserialize it.
|
||||
Here is a simple example. We will deserialize a *MyObj* struct. We need to load the request
|
||||
body first and then deserialize the json into an object.
|
||||
|
||||
```rust
|
||||
# extern crate actix_web;
|
||||
@ -124,14 +124,14 @@ fn index(req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> {
|
||||
# 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/).
|
||||
|
||||
|
||||
## JSON Response
|
||||
|
||||
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
|
||||
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 `T` must implement the `Serialize` trait from *serde*.
|
||||
|
||||
```rust
|
||||
@ -157,14 +157,14 @@ fn main() {
|
||||
|
||||
## Chunked transfer encoding
|
||||
|
||||
Actix automatically decode *chunked* encoding. `HttpRequest::payload()` already contains
|
||||
decoded bytes stream. If request payload compressed with one of supported
|
||||
compression codecs (br, gzip, deflate) bytes stream get decompressed.
|
||||
Actix automatically decodes *chunked* encoding. `HttpRequest::payload()` already contains
|
||||
the decoded byte stream. If the request payload is compressed with one of the supported
|
||||
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.
|
||||
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.
|
||||
|
||||
@ -187,13 +187,13 @@ fn index(req: HttpRequest) -> HttpResponse {
|
||||
|
||||
## Multipart body
|
||||
|
||||
Actix provides multipart stream support.
|
||||
[*Multipart*](../actix_web/multipart/struct.Multipart.html) is implemented as
|
||||
a stream of multipart items, each item could be
|
||||
[*Field*](../actix_web/multipart/struct.Field.html) or nested *Multipart* stream.
|
||||
`HttpResponse::multipart()` method returns *Multipart* stream for current request.
|
||||
Actix provides multipart stream support.
|
||||
[*Multipart*](../actix_web/multipart/struct.Multipart.html) is implemented as
|
||||
a stream of multipart items, each item can be a
|
||||
[*Field*](../actix_web/multipart/struct.Field.html) or a nested *Multipart* stream.
|
||||
`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
|
||||
# extern crate actix_web;
|
||||
@ -206,7 +206,7 @@ fn index(req: HttpRequest) -> Box<Future<...>> {
|
||||
// Handle multipart Field
|
||||
multipart::MultipartItem::Field(field) => {
|
||||
println!("==== FIELD ==== {:?} {:?}", field.headers(), field.content_type());
|
||||
|
||||
|
||||
Either::A(
|
||||
// Field in turn is a stream of *Bytes* objects
|
||||
field.map(|chunk| {
|
||||
@ -215,7 +215,7 @@ fn index(req: HttpRequest) -> Box<Future<...>> {
|
||||
.fold((), |_, _| result(Ok(()))))
|
||||
},
|
||||
multipart::MultipartItem::Nested(mp) => {
|
||||
// Or item could be nested Multipart stream
|
||||
// Or item could be nested Multipart stream
|
||||
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/).
|
||||
|
||||
## Urlencoded body
|
||||
|
||||
Actix provides support for *application/x-www-form-urlencoded* encoded body.
|
||||
`HttpResponse::urlencoded()` method returns
|
||||
[*UrlEncoded*](../actix_web/dev/struct.UrlEncoded.html) future, it resolves
|
||||
Actix provides support for *application/x-www-form-urlencoded* encoded bodies.
|
||||
`HttpResponse::urlencoded()` returns a
|
||||
[*UrlEncoded*](../actix_web/dev/struct.UrlEncoded.html) future, which resolves
|
||||
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`
|
||||
* transfer encoding is `chunked`.
|
||||
@ -261,10 +261,10 @@ fn index(mut req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> {
|
||||
|
||||
## 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.
|
||||
|
||||
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
|
||||
# extern crate actix_web;
|
||||
|
@ -1,14 +1,14 @@
|
||||
# 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.
|
||||
|
||||
## Unit tests
|
||||
|
||||
For unit testing actix provides request builder type and simple handler runner.
|
||||
[*TestRequest*](../actix_web/test/struct.TestRequest.html) implements builder-like pattern.
|
||||
You can generate `HttpRequest` instance with `finish()` method or you can
|
||||
run your handler with `run()` or `run_async()` methods.
|
||||
For unit testing actix provides a request builder type and simple handler runner.
|
||||
[*TestRequest*](../actix_web/test/struct.TestRequest.html) implements a builder-like pattern.
|
||||
You can generate a `HttpRequest` instance with `finish()` or you can
|
||||
run your handler with `run()` or `run_async()`.
|
||||
|
||||
```rust
|
||||
# extern crate http;
|
||||
@ -42,15 +42,15 @@ fn main() {
|
||||
|
||||
## 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)
|
||||
server that could be used to run whole application of just specific handlers
|
||||
in real http server. *TrstServer::get()*, *TrstServer::post()* or *TrstServer::client()*
|
||||
methods could be used to send request to test server.
|
||||
server that can be used to run the whole application of just specific handlers
|
||||
in real http server. *TestServer::get()*, *TestServer::post()* or *TestServer::client()*
|
||||
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*
|
||||
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.
|
||||
|
||||
```rust
|
||||
@ -73,8 +73,8 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
Other option is to use application factory. In this case you need to pass factory function
|
||||
same as you use for real http server configuration.
|
||||
The other option is to use an application factory. In this case you need to pass the factory
|
||||
function same way as you would for real http server configuration.
|
||||
|
||||
```rust
|
||||
# extern crate http;
|
||||
@ -105,13 +105,13 @@ fn main() {
|
||||
|
||||
## WebSocket server tests
|
||||
|
||||
It is possible to register *handler* with `TestApp::handler()` method that
|
||||
initiate web socket connection. *TestServer* provides `ws()` which connects to
|
||||
websocket server and returns ws reader and writer objects. *TestServer* also
|
||||
provides `execute()` method which runs future object to completion and returns
|
||||
It is possible to register a *handler* with `TestApp::handler()` that
|
||||
initiates a web socket connection. *TestServer* provides `ws()` which connects to
|
||||
the websocket server and returns ws reader and writer objects. *TestServer* also
|
||||
provides an `execute()` method which runs future objects to completion and returns
|
||||
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
|
||||
# extern crate actix;
|
||||
@ -147,7 +147,7 @@ fn main() {
|
||||
let (reader, mut writer) = srv.ws().unwrap(); // <- connect to ws server
|
||||
|
||||
writer.text("text"); // <- send message to server
|
||||
|
||||
|
||||
let (item, reader) = srv.execute(reader.into_future()).unwrap(); // <- wait for one message
|
||||
assert_eq!(item, Some(ws::Message::Text("text".to_owned())));
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
# WebSockets
|
||||
|
||||
Actix supports WebSockets out-of-the-box. It is possible to convert request's `Payload`
|
||||
to a stream of [*ws::Message*](../actix_web/ws/enum.Message.html) with
|
||||
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
|
||||
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
|
||||
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
|
||||
# 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).
|
||||
|
||||
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/)
|
||||
|
Loading…
Reference in New Issue
Block a user