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