From a3f124685a642061b0bdef996bff00da2d37c71d Mon Sep 17 00:00:00 2001 From: memoryruins Date: Thu, 5 Apr 2018 18:32:04 -0400 Subject: [PATCH 01/10] Remove redundant quickstart paragraph. --- guide/src/qs_1.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/guide/src/qs_1.md b/guide/src/qs_1.md index e73f65627..f3dda1ccd 100644 --- a/guide/src/qs_1.md +++ b/guide/src/qs_1.md @@ -1,8 +1,5 @@ # Quick start -Before you can start writing a actix web applications, you’ll need a version of Rust installed. -We recommend you use rustup to install or configure such a version. - ## Install Rust Before we begin, we need to install Rust using the [rustup](https://www.rustup.rs/) installer: From 46e6641528de2a747507453b24278bbd55c33393 Mon Sep 17 00:00:00 2001 From: memoryruins Date: Thu, 5 Apr 2018 18:46:36 -0400 Subject: [PATCH 02/10] Add repository hyperlink and trim repeat. --- guide/src/qs_1.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/guide/src/qs_1.md b/guide/src/qs_1.md index f3dda1ccd..343f4419e 100644 --- a/guide/src/qs_1.md +++ b/guide/src/qs_1.md @@ -2,7 +2,7 @@ ## Install Rust -Before we begin, we need to install Rust using the [rustup](https://www.rustup.rs/) installer: +Before we begin, we need to install Rust using the [rustup](https://www.rustup.rs/): ```bash curl https://sh.rustup.rs -sSf | sh @@ -18,9 +18,9 @@ Actix web framework requires rust version 1.21 and up. ## Running Examples -The fastest way to start experimenting with actix web is to clone the actix web repository -and run the included examples in the examples/ directory. The following set of -commands runs the `basics` example: +The fastest way to start experimenting with actix web is to clone the [repository](https://github.com/actix/actix-web) and run the included examples. + +The following set of commands runs the `basics` example: ```bash git clone https://github.com/actix/actix-web From 9f45cfe49264a45ed964f21d52ad930887978e55 Mon Sep 17 00:00:00 2001 From: memoryruins Date: Thu, 5 Apr 2018 19:12:23 -0400 Subject: [PATCH 03/10] Expand note about actix. --- guide/src/qs_2.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/guide/src/qs_2.md b/guide/src/qs_2.md index e405775d4..8c061f57f 100644 --- a/guide/src/qs_2.md +++ b/guide/src/qs_2.md @@ -3,7 +3,7 @@ Let’s create and run our first actix web application. We’ll create a new Cargo project that depends on actix web and then run the application. -In the previous section we already installed the required rust version. Now let's create new cargo projects. +In the previous section we already installed the required rust version. Now let's create a new cargo project. ## Hello, world! @@ -24,7 +24,7 @@ actix = "0.5" actix-web = "0.4" ``` -In order to implement a web server, first we need to create a request handler. +In order to implement a web server, we first need to create a request handler. A request handler is a function that accepts an `HttpRequest` instance as its only parameter and returns a type that can be converted into `HttpResponse`: @@ -64,7 +64,7 @@ connections. The server accepts a function that should return an `HttpHandler` i .run(); ``` -That's it. Now, compile and run the program with `cargo run`. +That's it! Now, compile and run the program with `cargo run`. Head over to ``http://localhost:8088/`` to see the results. Here is full source of main.rs file: @@ -80,7 +80,7 @@ fn index(req: HttpRequest) -> &'static str { fn main() { # // In the doctest suite we can't run blocking code - deliberately leak a thread -# // If copying this example in show-all mode make sure you skip the thread spawn +# // If copying this example in show-all mode, make sure you skip the thread spawn # // call. # thread::spawn(|| { HttpServer::new( @@ -92,7 +92,11 @@ fn main() { } ``` -Note on the `actix` crate. Actix web framework is built on top of actix actor library. +> **Note**: actix web is built upon [actix](https://github.com/actix/actix), +> an [actor model](https://en.wikipedia.org/wiki/Actor_model) framework in Rust. + `actix::System` initializes actor system, `HttpServer` is an actor and must run within a -properly configured actix system. For more information please check -[actix documentation](https://actix.github.io/actix/actix/) +properly configured actix system. + +> For more information, check out the [actix documentation](https://actix.github.io/actix/actix/) +> and [actix guide](https://actix.github.io/actix/guide/). From a0f1ff7eb3d5058aec186cbe684f7585627f0698 Mon Sep 17 00:00:00 2001 From: memoryruins Date: Thu, 5 Apr 2018 19:21:29 -0400 Subject: [PATCH 04/10] Add src directory to main.rs and list on first codeblock. --- guide/src/qs_2.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/guide/src/qs_2.md b/guide/src/qs_2.md index 8c061f57f..543347ccc 100644 --- a/guide/src/qs_2.md +++ b/guide/src/qs_2.md @@ -1,14 +1,10 @@ # Getting Started -Let’s create and run our first actix web application. We’ll create a new Cargo project -that depends on actix web and then run the application. - -In the previous section we already installed the required rust version. Now let's create a new cargo project. +Let’s write our first actix web application! ## Hello, world! -Let’s write our first actix web application! Start by creating a new binary-based -Cargo project and changing into the new directory: +Start by creating a new binary-based Cargo project and changing into the new directory: ```bash cargo new hello-world --bin @@ -29,6 +25,7 @@ In order to implement a web server, we first need to create a request handler. A request handler is a function that accepts an `HttpRequest` instance as its only parameter and returns a type that can be converted into `HttpResponse`: +Filename: src/main.rs ```rust # extern crate actix_web; # use actix_web::*; @@ -67,7 +64,7 @@ connections. The server accepts a function that should return an `HttpHandler` i That's it! Now, compile and run the program with `cargo run`. Head over to ``http://localhost:8088/`` to see the results. -Here is full source of main.rs file: +The full source of src/main.rs is listed below: ```rust # use std::thread; From 3c93e0c654501900f050bba7e24da6b1d46ea852 Mon Sep 17 00:00:00 2001 From: memoryruins Date: Thu, 5 Apr 2018 19:25:41 -0400 Subject: [PATCH 05/10] Add newline for reading source. --- guide/src/qs_1.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/guide/src/qs_1.md b/guide/src/qs_1.md index 343f4419e..aac24a7de 100644 --- a/guide/src/qs_1.md +++ b/guide/src/qs_1.md @@ -18,7 +18,8 @@ Actix web framework requires rust version 1.21 and up. ## Running Examples -The fastest way to start experimenting with actix web is to clone the [repository](https://github.com/actix/actix-web) and run the included examples. +The fastest way to start experimenting with actix web is to clone the +[repository](https://github.com/actix/actix-web) and run the included examples. The following set of commands runs the `basics` example: From c2ad65a61dc498d46a4b417891e885b17b51f9a4 Mon Sep 17 00:00:00 2001 From: memoryruins Date: Thu, 5 Apr 2018 19:43:17 -0400 Subject: [PATCH 06/10] Various tweaks to Application chapter. --- guide/src/qs_3.md | 55 ++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/guide/src/qs_3.md b/guide/src/qs_3.md index bcfdee8ad..32cd6bfb4 100644 --- a/guide/src/qs_3.md +++ b/guide/src/qs_3.md @@ -1,20 +1,21 @@ # Application -Actix web provides some primitives to build web servers and applications with Rust. -It provides routing, middlewares, pre-processing of requests, and post-processing of responses, +Actix web provides various primitives to build web servers and applications with Rust. +It provides routing, middlewares, pre-processing of requests, post-processing of responses, websocket protocol handling, multipart streams, etc. All actix web servers are built around the `App` instance. -It is used for registering routes for resources, and middlewares. -It also stores application specific state that is shared across all handlers -within same application. +It is used for registering routes for resources and middlewares. +It also stores application state shared across all handlers within same application. -Application acts as a namespace for all routes, i.e all routes for a specific application +Applications act as a namespace for all routes, i.e all routes for a specific application have the same url path prefix. The application prefix always contains a leading "/" slash. -If supplied prefix does not contain leading slash, it gets inserted. -The prefix should consist of value path segments. i.e for an application with prefix `/app` -any request with the paths `/app`, `/app/` or `/app/test` would match, -but path `/application` would not match. +If a supplied prefix does not contain leading slash, it is automatically inserted. +The prefix should consist of value path segments. + +> For an application with prefix `/app`, +> any request with the paths `/app`, `/app/`, or `/app/test` would match; +> however, the path `/application` would not match. ```rust,ignore # extern crate actix_web; @@ -31,10 +32,11 @@ but path `/application` would not match. # } ``` -In this example application with `/app` prefix and `index.html` resource -gets created. This resource is available as on `/app/index.html` url. -For more information check -[*URL Matching*](./qs_5.html#using-a-application-prefix-to-compose-applications) section. +In this example, an application with the `/app` prefix and a `index.html` resource +are created. This resource is available through the `/app/index.html` url. + +> For more information, check the +> [URL Dispatch](./qs_5.html#using-a-application-prefix-to-compose-applications) section. Multiple applications can be served with one server: @@ -59,18 +61,17 @@ fn main() { } ``` -All `/app1` requests route to the first application, `/app2` to the second and then all other to the third. -Applications get matched based on registration order, if an application with more general -prefix is registered before a less generic one, that would effectively block the less generic -application from getting matched. For example, if *application* with prefix "/" gets registered -as first application, it would match all incoming requests. +All `/app1` requests route to the first application, `/app2` to the second, and all other to the third. +**Applications get matched based on registration order**. If an application with a more generic +prefix is registered before a less generic one, it would effectively block the less generic +application matching. For example, if an `App` with the prefix `"/"` was registered +as the first application, it would match all incoming requests. ## State Application state is shared with all routes and resources within the same application. -State can be accessed with the `HttpRequest::state()` method as a read-only, -but an interior mutability pattern with `RefCell` can be used to achieve state mutability. -State can be accessed with `HttpContext::state()` when using an http actor. +When using an http actor,state can be accessed with the `HttpRequest::state()` as read-only, +but interior mutability with `RefCell` can be used to achieve state mutability. State is also available for route matching predicates and middlewares. Let's write a simple application that uses shared state. We are going to store request count @@ -102,8 +103,8 @@ fn main() { } ``` -Note on application state, http server accepts an application factory rather than an application -instance. Http server constructs an application instance for each thread, so application state -must be constructed multiple times. If you want to share state between different threads, a -shared object should be used, like `Arc`. Application state does not need to be `Send` and `Sync` -but the application factory must be `Send` + `Sync`. +> **Note**: http server accepts an application factory rather than an application +> instance. Http server constructs an application instance for each thread, thus application state +> must be constructed multiple times. If you want to share state between different threads, a +> shared object should be used, e.g. `Arc`. Application state does not need to be `Send` and `Sync`, +> but the application factory must be `Send` + `Sync`. From 7f0de705a39bf79d259eec82afe4d4902c7da4a4 Mon Sep 17 00:00:00 2001 From: memoryruins Date: Thu, 5 Apr 2018 20:55:19 -0400 Subject: [PATCH 07/10] Tweaks to Server chapter. --- guide/src/qs_3_5.md | 96 ++++++++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 44 deletions(-) diff --git a/guide/src/qs_3_5.md b/guide/src/qs_3_5.md index 274524024..65d8ed71f 100644 --- a/guide/src/qs_3_5.md +++ b/guide/src/qs_3_5.md @@ -1,13 +1,19 @@ # Server -The [*HttpServer*](../actix_web/struct.HttpServer.html) type is responsible for -serving http requests. *HttpServer* accepts application factory as a parameter, -Application factory must have `Send` + `Sync` boundaries. More about that in the -*multi-threading* section. To bind to a specific socket address, `bind()` must be used. -This method can be called multiple times. To start the http server, one of the *start* -methods can be used. `start()` method starts a simple server, `start_tls()` or `start_ssl()` -starts ssl server. *HttpServer* is an actix actor, it has to be initialized -within a properly configured actix system: +The [**HttpServer**](../actix_web/struct.HttpServer.html) type is responsible for +serving http requests. + +`HttpServer` accepts an application factory as a parameter, and the +application factory must have `Send` + `Sync` boundaries. More about that in the +*multi-threading* section. + +To bind to a specific socket address, `bind()` must be used, and it may be called multiple times. +To start the http server, one of the start methods. + +- use `start()` for a simple server +- use `start_tls()` or `start_ssl()` for a ssl server + +`HttpServer` is an actix actor. It must be initialized within a properly configured actix system: ```rust # extern crate actix; @@ -29,17 +35,17 @@ fn main() { } ``` -It is possible to start a server in a separate thread with the *spawn()* method. In that -case the server spawns a new thread and creates a new actix system in it. To stop -this server, send a `StopServer` message. +> It is possible to start a server in a separate thread with the `spawn()` method. In that +> case the server spawns a new thread and creates a new actix system in it. To stop +> this server, send a `StopServer` message. -Http server is implemented as an actix actor. It is possible to communicate with the server -via a messaging system. All start methods like `start()`, `start_ssl()`, etc. return the -address of the started http server. Actix http server accepts several messages: +`HttpServer` is implemented as an actix actor. It is possible to communicate with the server +via a messaging system. All start methods, e.g. `start()` and `start_ssl()`, return the +address of the started http server. It accepts several messages: -* `PauseServer` - Pause accepting incoming connections -* `ResumeServer` - Resume accepting incoming connections -* `StopServer` - Stop incoming connection processing, stop all workers and exit +- `PauseServer` - Pause accepting incoming connections +- `ResumeServer` - Resume accepting incoming connections +- `StopServer` - Stop incoming connection processing, stop all workers and exit ```rust # extern crate futures; @@ -74,7 +80,7 @@ fn main() { ## Multi-threading -Http server automatically starts an number of http workers, by default +`HttpServer` automatically starts an number of http workers, by default this number is equal to number of logical CPUs in the system. This number can be overridden with the `HttpServer::threads()` method. @@ -92,8 +98,10 @@ fn main() { ``` The server creates a separate application instance for each created worker. Application state -is not shared between threads, to share state `Arc` could be used. Application state -does not need to be `Send` and `Sync` but application factory must be `Send` + `Sync`. +is not shared between threads. To share state, `Arc` could be used. + +> Application state does not need to be `Send` and `Sync`, +> but factories must be `Send` + `Sync`. ## SSL @@ -123,22 +131,21 @@ fn main() { } ``` -Note on *HTTP/2.0* protocol over tls without prior knowledge, it requires -[tls alpn](https://tools.ietf.org/html/rfc7301). At the moment only -`openssl` has `alpn ` support. - -Please check [example](https://github.com/actix/actix-web/tree/master/examples/tls) -for a full example. +> **Note**: the *HTTP/2.0* protocol requires +> [tls alpn](https://tools.ietf.org/html/rfc7301). +> At the moment, only `openssl` has `alpn` support. +> For a full example, check out +> [examples/tls](https://github.com/actix/actix-web/tree/master/examples/tls). ## Keep-Alive -Actix can wait for requests on a keep-alive connection. *Keep alive* -connection behavior is defined by server settings. +Actix can wait for requests on a keep-alive connection. - * `75` or `Some(75)` or `KeepAlive::Timeout(75)` - enable 75 sec *keep alive* timer according - request and response settings. - * `None` or `KeepAlive::Disabled` - disable *keep alive*. - * `KeepAlive::Tcp(75)` - Use `SO_KEEPALIVE` socket option. +> *keep alive* connection behavior is defined by server settings. + +- `75`, `Some(75)`, `KeepAlive::Timeout(75)` - enable 75 second *keep alive* timer. +- `None` or `KeepAlive::Disabled` - disable *keep alive*. +- `KeepAlive::Tcp(75)` - use `SO_KEEPALIVE` socket option. ```rust # extern crate actix_web; @@ -163,11 +170,12 @@ fn main() { } ``` -If first option is selected then *keep alive* state is +If the first option is selected, then *keep alive* state is calculated based on the response's *connection-type*. By default -`HttpResponse::connection_type` is not defined in that case *keep alive* -defined by request's http version. Keep alive is off for *HTTP/1.0* -and is on for *HTTP/1.1* and *HTTP/2.0*. +`HttpResponse::connection_type` is not defined. In that case *keep alive* is +defined by the request's http version. + +> *keep alive* is **off** for *HTTP/1.0* and is **on** for *HTTP/1.1* and *HTTP/2.0*. *Connection type* can be change with `HttpResponseBuilder::connection_type()` method. @@ -186,19 +194,19 @@ fn index(req: HttpRequest) -> HttpResponse { ## Graceful shutdown -Actix http server supports graceful shutdown. After receiving a stop signal, workers -have a specific amount of time to finish serving requests. Workers still alive after the +`HttpServer` supports graceful shutdown. After receiving a stop signal, workers +have a specific amount of time to finish serving requests. Any workers still alive after the timeout are force-dropped. By default the shutdown timeout is set to 30 seconds. You can change this parameter with the `HttpServer::shutdown_timeout()` method. You can send a stop message to the server with the server address and specify if you want -graceful shutdown or not. The `start()` methods return address of the server. +graceful shutdown or not. The `start()` methods returns address of the server. -Http server handles several OS signals. *CTRL-C* is available on all OSs, +`HttpServer` handles several OS signals. *CTRL-C* is available on all OSs, other signals are available on unix systems. -* *SIGINT* - Force shutdown workers -* *SIGTERM* - Graceful shutdown workers -* *SIGQUIT* - Force shutdown workers +- *SIGINT* - Force shutdown workers +- *SIGTERM* - Graceful shutdown workers +- *SIGQUIT* - Force shutdown workers -It is possible to disable signal handling with `HttpServer::disable_signals()` method. +> It is possible to disable signal handling with `HttpServer::disable_signals()` method. From 961edfd21add398754a79833eb94a866064b860c Mon Sep 17 00:00:00 2001 From: memoryruins Date: Thu, 5 Apr 2018 21:30:52 -0400 Subject: [PATCH 08/10] 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; From 0f86c596fac4f29e367cc2c0528e1d81a0bbcbde Mon Sep 17 00:00:00 2001 From: memoryruins Date: Thu, 5 Apr 2018 21:54:39 -0400 Subject: [PATCH 09/10] Tweaks to Errors chapter. --- guide/src/qs_4_5.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/guide/src/qs_4_5.md b/guide/src/qs_4_5.md index cf8c6ef36..4bc82451d 100644 --- a/guide/src/qs_4_5.md +++ b/guide/src/qs_4_5.md @@ -1,10 +1,11 @@ # Errors -Actix uses [`Error` type](../actix_web/error/struct.Error.html) +Actix uses the [`Error` type](../actix_web/error/struct.Error.html) and [`ResponseError` trait](../actix_web/error/trait.ResponseError.html) for handling handler's errors. + Any error that implements the `ResponseError` trait can be returned as an error value. -*Handler* can return an *Result* object; actix by default provides +`Handler` can return an `Result` object. By default, actix provides a `Responder` implementation for compatible result types. Here is the implementation definition: @@ -12,7 +13,8 @@ definition: impl> Responder for Result ``` -And any error that implements `ResponseError` can be converted into an `Error` object. +Any error that implements `ResponseError` can be converted into an `Error` object. + For example, if the *handler* function returns `io::Error`, it would be converted into an `HttpInternalServerError` response. Implementation for `io::Error` is provided by default. @@ -35,7 +37,7 @@ fn index(req: HttpRequest) -> io::Result { ## Custom error response -To add support for custom errors, all we need to do is just implement the `ResponseError` trait +To add support for custom errors, all we need to do is implement the `ResponseError` trait for the custom error type. The `ResponseError` trait has a default implementation for the `error_response()` method: it generates a *500* response. @@ -109,7 +111,7 @@ fn index(req: HttpRequest) -> Result<&'static str, MyError> { ## Error helpers Actix provides a set of error helper types. It is possible to use them for generating -specific error responses. We can use helper types for the first example with custom error. +specific error responses. We can use the helper types for the first example with a custom error. ```rust # extern crate actix_web; From 2a543001e0a65f5cce1e9cde3e3171f39e9ea42d Mon Sep 17 00:00:00 2001 From: memoryruins Date: Thu, 5 Apr 2018 22:12:20 -0400 Subject: [PATCH 10/10] Tweaks to the URL Dispatch chapter. --- guide/src/qs_5.md | 67 +++++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/guide/src/qs_5.md b/guide/src/qs_5.md index f97840a06..6f66af439 100644 --- a/guide/src/qs_5.md +++ b/guide/src/qs_5.md @@ -2,17 +2,19 @@ URL dispatch provides a simple way for mapping URLs to `Handler` code using a simple pattern matching language. If one of the patterns matches the path information associated with a request, -a particular handler object is invoked. A handler is a specific object that implements the -`Handler` trait, defined in your application, that receives the request and returns -a response object. More information is available in the [handler section](../qs_4.html). +a particular handler object is invoked. + +> A handler is a specific object that implements the +> `Handler` trait, defined in your application, that receives the request and returns +> a response object. More information is available in the [handler section](../qs_4.html). ## Resource configuration Resource configuration is the act of adding a new resources to an application. A resource has a name, which acts as an identifier to be used for URL generation. The name also allows developers to add routes to existing resources. -A resource also has a pattern, meant to match against the *PATH* portion of a *URL*, -it does not match against the *QUERY* portion (the portion following the scheme and +A resource also has a pattern, meant to match against the *PATH* portion of a *URL*. +It does not match against the *QUERY* portion (the portion following the scheme and port, e.g., */foo/bar* in the *URL* *http://localhost:8080/foo/bar?q=value*). The [App::resource](../actix_web/struct.App.html#method.resource) methods @@ -43,7 +45,7 @@ The *Configuration function* has the following type: ``` The *Configuration function* can set a name and register specific routes. -If a resource does not contain any route or does not have any matching routes it +If a resource does not contain any route or does not have any matching routes, it returns *NOT FOUND* http response. ## Configuring a Route @@ -55,8 +57,9 @@ all requests and the default handler is `HttpNotFound`. The application routes incoming requests based on route criteria which are defined during resource registration and route registration. Resource matches all routes it contains in -the order the routes were registered via `Resource::route()`. A *Route* can contain -any number of *predicates* but only one handler. +the order the routes were registered via `Resource::route()`. + +> A *Route* can contain any number of *predicates* but only one handler. ```rust # extern crate actix_web; @@ -74,10 +77,11 @@ fn main() { } ``` -In this example `HttpResponse::Ok()` is returned for *GET* requests, -if request contains `Content-Type` header and value of this header is *text/plain* -and path equals to `/path`. Resource calls handle of the first matching route. -If a resource can not match any route a "NOT FOUND" response is returned. +In this example, `HttpResponse::Ok()` is returned for *GET* requests. +If a request contains `Content-Type` header, the value of this header is *text/plain*, +and path equals to `/path`, Resource calls handle of the first matching route. + +If a resource can not match any route, a "NOT FOUND" response is returned. [*Resource::route()*](../actix_web/struct.Resource.html#method.route) returns a [*Route*](../actix_web/struct.Route.html) object. Route can be configured with a @@ -118,9 +122,7 @@ arguments provided to a route configuration returns `false` during a check, that skipped and route matching continues through the ordered set of routes. If any route matches, the route matching process stops and the handler associated with -the route is invoked. - -If no route matches after all route patterns are exhausted, a *NOT FOUND* response get returned. +the route is invoked. If no route matches after all route patterns are exhausted, a *NOT FOUND* response get returned. ## Resource pattern syntax @@ -208,8 +210,9 @@ For example, for the URL */abc/*: * */abc/{foo}* will not match. * */{foo}/* will match. -Note that path will be URL-unquoted and decoded into valid unicode string before -matching pattern and values representing matched path segments will be URL-unquoted too. +> **Note**: path will be URL-unquoted and decoded into valid unicode string before +> matching pattern and values representing matched path segments will be URL-unquoted too. + So for instance, the following pattern: ``` @@ -292,11 +295,11 @@ any) is skipped. For security purposes, if a segment meets any of the following conditions, an `Err` is returned indicating the condition met: - * Decoded segment starts with any of: `.` (except `..`), `*` - * Decoded segment ends with any of: `:`, `>`, `<` - * Decoded segment contains any of: `/` - * On Windows, decoded segment contains any of: '\' - * Percent-encoding results in invalid UTF8. +* Decoded segment starts with any of: `.` (except `..`), `*` +* Decoded segment ends with any of: `:`, `>`, `<` +* Decoded segment contains any of: `/` +* On Windows, decoded segment contains any of: '\' +* Percent-encoding results in invalid UTF8. As a result of these conditions, a `PathBuf` parsed from request path parameter is safe to interpolate within, or use as a suffix of, a path without additional checks. @@ -350,8 +353,8 @@ fn main() { } ``` -It also possible to extract path information to a tuple, in this case you don't need -to define extra type, just use tuple for as a `Path` generic type. +It also possible to extract path information to a tuple. In this case, you don't need +to define an extra type; use a tuple as a `Path` generic type. Here is previous example re-written using tuple instead of specific type. @@ -433,21 +436,21 @@ fn main() { By normalizing it means: - - Add a trailing slash to the path. - - Double slashes are replaced by one. +* Add a trailing slash to the path. +* Double slashes are replaced by one. The handler returns as soon as it finds a path that resolves correctly. The order if all enable is 1) merge, 3) both merge and append and 3) append. If the path resolves with at least one of those conditions, it will redirect to the new path. -If *append* is *true* append slash when needed. If a resource is +If *append* is *true*, append slash when needed. If a resource is defined with trailing slash and the request doesn't have one, it will be appended automatically. If *merge* is *true*, merge multiple consecutive slashes in the path into one. -This handler designed to be use as a handler for application's *default resource*. +This handler designed to be used as a handler for application's *default resource*. ```rust # extern crate actix_web; @@ -468,7 +471,7 @@ fn main() { In this example `/resource`, `//resource///` will be redirected to `/resource/`. -In this example path normalization handler is registered for all methods, +In this example, the path normalization handler is registered for all methods, but you should not rely on this mechanism to redirect *POST* requests. The redirect of the slash-appending *Not Found* will turn a *POST* request into a GET, losing any *POST* data in the original request. @@ -493,7 +496,7 @@ fn main() { ## Using an Application Prefix to Compose Applications -The `App::prefix()`" method allows to set a specific application prefix. +The `App::prefix()` method allows to set a specific application prefix. This prefix represents a resource prefix that will be prepended to all resource patterns added by the resource configuration. This can be used to help mount a set of routes at a different location than the included callable's author intended while still maintaining the same @@ -556,7 +559,7 @@ fn main() { } ``` -In this example *index* handler will be called only if request contains *CONTENT-TYPE* header. +In this example, *index* handler will be called only if request contains *CONTENT-TYPE* header. Predicates have access to the application's state via `HttpRequest::state()`. Also predicates can store extra information in @@ -565,7 +568,7 @@ Also predicates can store extra information in ### Modifying predicate values You can invert the meaning of any predicate value by wrapping it in a `Not` predicate. -For example if you want to return "METHOD NOT ALLOWED" response for all methods +For example, if you want to return "METHOD NOT ALLOWED" response for all methods except "GET": ```rust