mirror of
https://github.com/fafhrd91/actix-web
synced 2024-11-24 08:22:59 +01:00
guide: improve wording & style
This commit is contained in:
parent
36161aba99
commit
368103dd09
@ -1,6 +1,6 @@
|
|||||||
# Quick start
|
# 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.
|
We recommend you use rustup to install or configure such a version.
|
||||||
|
|
||||||
## Install Rust
|
## Install Rust
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
@ -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).
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
Let’s create and run our first actix web application. We’ll create a new Cargo project
|
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.
|
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
|
Let’s 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/)
|
||||||
|
@ -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`.
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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())));
|
||||||
}
|
}
|
||||||
|
@ -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/)
|
||||||
|
Loading…
Reference in New Issue
Block a user