diff --git a/guide/src/qs_1.md b/guide/src/qs_1.md index aac24a7d..5e31aec6 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/): +Before we begin, we need to install Rust using [rustup](https://www.rustup.rs/): ```bash curl https://sh.rustup.rs -sSf | sh diff --git a/guide/src/qs_10.md b/guide/src/qs_10.md index ce1ed4a7..d4b4addf 100644 --- a/guide/src/qs_10.md +++ b/guide/src/qs_10.md @@ -1,23 +1,25 @@ # Middleware -Actix' middleware system allows to add additional behavior to request/response processing. -Middleware can hook into incoming request process and modify request or halt request -processing and return response early. Also it can hook into response processing. +Actix's middleware system allows us to add additional behavior to request/response processing. +Middleware can hook into an incoming request process, enabling us to modify requests +as well as halt request processing to return a response early. -Typically middlewares are involved in the following actions: +Middleware can also hook into response processing. + +Typically, middleware is involved in the following actions: * Pre-process the Request * Post-process a Response * Modify application state * Access external services (redis, logging, sessions) -Middlewares are registered for each application and are executed in same order as -registration order. In general, a *middleware* is a type that implements the +Middleware is registered for each application and executed in same order as +registration. In general, a *middleware* is a type that implements the [*Middleware trait*](../actix_web/middlewares/trait.Middleware.html). Each method in this trait has a default implementation. Each method can return a result immediately or a *future* object. -Here is an example of a simple middleware that adds request and response headers: +The following demonstrates using middleware to add request and response headers: ```rust # extern crate http; @@ -57,16 +59,17 @@ fn main() { } ``` -Actix provides several useful middlewares, like *logging*, *user sessions*, etc. - +> Actix provides several useful middlewares, such as *logging*, *user sessions*, etc. ## Logging Logging is implemented as a middleware. It is common to register a logging middleware as the first middleware for the application. -Logging middleware has to be registered for each application. *Logger* middleware -uses 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). +Logging middleware must be registered for each application. + +The `Logger` middleware uses the standard log crate to log information. You should enable logger +for *actix_web* package to see access log ([env_logger](https://docs.rs/env_logger/*/env_logger/) +or similar). ### Usage @@ -76,6 +79,7 @@ Default `Logger` can be created with `default` method, it uses the default forma ```ignore %a %t "%r" %s %b "%{Referer}i" "%{User-Agent}i" %T ``` + ```rust # extern crate actix_web; extern crate env_logger; @@ -93,7 +97,7 @@ fn main() { } ``` -Here is an example of the default logging format: +The following 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 @@ -126,12 +130,11 @@ INFO:actix_web::middleware::logger: 127.0.0.1:59947 [02/Dec/2017:00:22:40 -0800] `%{FOO}e` os.environ['FOO'] - ## Default headers -To set default response headers the `DefaultHeaders` middleware can be used. The +To set default response headers, the `DefaultHeaders` middleware can be used. The *DefaultHeaders* middleware does not set the header if response headers already contain -the specified header. +a specified header. ```rust # extern crate actix_web; @@ -153,27 +156,28 @@ fn main() { ## User sessions Actix provides a general solution for session management. The -[*Session storage*](../actix_web/middleware/struct.SessionStorage.html) middleware can be +[**SessionStorage**](../actix_web/middleware/struct.SessionStorage.html) middleware can be used with different backend types to store session data in different backends. -By default only cookie session backend is implemented. Other backend implementations -could be added later. -[*Cookie session backend*](../actix_web/middleware/struct.CookieSessionBackend.html) -uses signed cookies as session storage. *Cookie session backend* creates sessions which -are limited to storing fewer than 4000 bytes of data (as the payload must fit into a -single cookie). Internal server error is generated if session contains more than 4000 bytes. +> By default, only cookie session backend is implemented. Other backend implementations +> can be added. -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. -Note that whatever you write into your session is visible by the user (but not modifiable). +[**CookieSessionBackend**](../actix_web/middleware/struct.CookieSessionBackend.html) +uses signed cookies as session storage. `CookieSessionBackend` creates sessions which +are limited to storing fewer than 4000 bytes of data, as the payload must fit into a +single cookie. An internal server error is generated if a session contains more than 4000 bytes. -In general case, you create -[*Session storage*](../actix_web/middleware/struct.SessionStorage.html) middleware -and initializes it with specific backend implementation, like *CookieSessionBackend*. -To access session data +You need to pass a random value to the constructor of `CookieSessionBackend`. +This is a private key for cookie session. When this value is changed, all session data is lost. + +> **Note**: anything you write into the session is visible by the user, but it is not modifiable. + +In general, you create a +`SessionStorage` middleware and initialize it with specific backend implementation, +such as a `CookieSessionBackend`. To access session data, [*HttpRequest::session()*](../actix_web/middleware/trait.RequestSession.html#tymethod.session) - has to be used. This method returns a -[*Session*](../actix_web/middleware/struct.Session.html) object, which allows to get or set + must be used. This method returns a +[*Session*](../actix_web/middleware/struct.Session.html) object, which allows us to get or set session data. ```rust @@ -212,12 +216,12 @@ fn main() { ## Error handlers -`ErrorHandlers` middleware allows to provide custom handlers for responses. +`ErrorHandlers` middleware allows us to provide custom handlers for responses. -You can use `ErrorHandlers::handler()` method to register a custom error handler -for specific status code. You can modify existing response or create completly new -one. Error handler can return response immediately or return future that resolves -to a response. +You can use the `ErrorHandlers::handler()` method to register a custom error handler +for a specific status code. You can modify an existing response or create a completly new +one. The error handler can return a response immediately or return a future that resolves +into a response. ```rust # extern crate actix_web; diff --git a/guide/src/qs_12.md b/guide/src/qs_12.md index 1da5f1ef..2feb5a1b 100644 --- a/guide/src/qs_12.md +++ b/guide/src/qs_12.md @@ -2,8 +2,8 @@ ## Individual file -It is possible to serve static files with custom path pattern and `NamedFile`. To -match path tail we can use `[.*]` regex. +It is possible to serve static files with a custom path pattern and `NamedFile`. To +match a path tail, we can use a `[.*]` regex. ```rust # extern crate actix_web; @@ -24,9 +24,9 @@ fn main() { ## Directory -To serve files from specific directory and sub-directories `StaticFiles` could be used. -`StaticFiles` must be registered with `App::handler()` method otherwise -it won't be able to serve sub-paths. +To serve files from specific directories and sub-directories, `StaticFiles` can be used. +`StaticFiles` must be registered with an `App::handler()` method, otherwise +it will be unable to serve sub-paths. ```rust # extern crate actix_web; @@ -39,11 +39,11 @@ fn main() { } ``` -First parameter is a base directory. Second parameter is *show_index*, if it is set to *true* -directory listing would be returned for directories, if it is set to *false* -then *404 Not Found* would be returned instead of directory listing. +The first parameter is the base directory. If the second parameter, *show_index*, is set to **true**, +the directory listing will be returned, and if it is set to **false**, +*404 Not Found* will be returned. -Instead of showing files listing for directory, it is possible to redirect to specific -index file. Use +Instead of showing files listing for directory, it is possible to redirect to a specific +index file. Use the [*StaticFiles::index_file()*](../actix_web/s/struct.StaticFiles.html#method.index_file) method to configure this redirect. diff --git a/guide/src/qs_13.md b/guide/src/qs_13.md index 753a9c16..963d5598 100644 --- a/guide/src/qs_13.md +++ b/guide/src/qs_13.md @@ -1,13 +1,15 @@ # HTTP/2.0 -Actix web automatically upgrades connection to *HTTP/2.0* if possible. +Actix web automatically upgrades connections to *HTTP/2.0* if possible. ## Negotiation *HTTP/2.0* protocol over tls without prior knowledge requires -[tls alpn](https://tools.ietf.org/html/rfc7301). At the moment only -`rust-openssl` has support. Turn on the `alpn` feature to enable `alpn` negotiation. -With enabled `alpn` feature `HttpServer` provides the +[tls alpn](https://tools.ietf.org/html/rfc7301). + +> Currently, only `rust-openssl` has support. + +`alpn` negotiation requires enabling the feature. When enabled, `HttpServer` provides the [serve_tls](../actix_web/struct.HttpServer.html#method.serve_tls) method. ```toml @@ -35,10 +37,10 @@ fn main() { } ``` -Upgrade to *HTTP/2.0* schema described in +Upgrades to *HTTP/2.0* schema described in [rfc section 3.2](https://http2.github.io/http2-spec/#rfc.section.3.2) is not supported. Starting *HTTP/2* with prior knowledge is supported for both clear text connection and tls connection. [rfc section 3.4](https://http2.github.io/http2-spec/#rfc.section.3.4) -Please check [example](https://github.com/actix/actix-web/tree/master/examples/tls) -for a concrete example. +> Check out [examples/tls](https://github.com/actix/actix-web/tree/master/examples/tls) +> for a concrete example. diff --git a/guide/src/qs_14.md b/guide/src/qs_14.md index a805e7a5..0d1998e4 100644 --- a/guide/src/qs_14.md +++ b/guide/src/qs_14.md @@ -2,13 +2,14 @@ ## Diesel -At the moment of 1.0 release Diesel does not support asynchronous operations. -But it possible to use the `actix` synchronous actor system as a db interface api. -Technically sync actors are worker style actors, multiple of them -can be run in parallel and process messages from same queue (sync actors work in mpsc mode). +At the moment, Diesel 1.0 does not support asynchronous operations, +but it possible to use the `actix` synchronous actor system as a database interface api. -Let's create a simple db api that can insert a new user row into an SQLite table. -We have to define sync actor and connection that this actor will use. The same approach +Technically, sync actors are worker style actors. Multiple sync actors +can be run in parallel and process messages from same queue. Sync actors work in mpsc mode. + +Let's create a simple database api that can insert a new user row into a SQLite table. +We must define a sync actor and a connection that this actor will use. The same approach can be used for other databases. ```rust,ignore @@ -21,7 +22,7 @@ impl Actor for DbExecutor { } ``` -This is the definition of our actor. Now we need to define the *create user* message and response. +This is the definition of our actor. Now, we must define the *create user* message and response. ```rust,ignore struct CreateUser { @@ -33,8 +34,8 @@ impl Message for CreateUser { } ``` -We can send a `CreateUser` message to the `DbExecutor` actor, and as a result we get a -`User` model instance. Now we need to define the actual handler implementation for this message. +We can send a `CreateUser` message to the `DbExecutor` actor, and as a result, we will receive a +`User` model instance. Next, we must define the handler implementation for this message. ```rust,ignore impl Handler for DbExecutor { @@ -67,7 +68,7 @@ impl Handler for DbExecutor { } ``` -That's it. Now we can use the *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 the address in a state where http handler can access it. @@ -97,9 +98,9 @@ fn main() { } ``` -And finally we can use the address in a request handler. We get a message response -asynchronously, so the handler needs to return a future object, also `Route::a()` needs to be -used for async handler registration. +We will use the address in a request handler. The handle returns a future object; +thus, we receive the message response asynchronously. +`Route::a()` must be used for async handler registration. ```rust,ignore @@ -120,8 +121,8 @@ fn index(req: HttpRequest) -> Box> } ``` -Full example is available in the -[examples directory](https://github.com/actix/actix-web/tree/master/examples/diesel/). +> A full example is available in the +> [examples directory](https://github.com/actix/actix-web/tree/master/examples/diesel/). -More information on sync actors can be found in the -[actix documentation](https://docs.rs/actix/0.5.0/actix/sync/index.html). +> More information on sync actors can be found in the +> [actix documentation](https://docs.rs/actix/0.5.0/actix/sync/index.html). diff --git a/guide/src/qs_7.md b/guide/src/qs_7.md index fab21a34..3e869451 100644 --- a/guide/src/qs_7.md +++ b/guide/src/qs_7.md @@ -4,10 +4,13 @@ A builder-like pattern is used to construct an instance of `HttpResponse`. `HttpResponse` provides several methods that return a `HttpResponseBuilder` instance, -which implements various convenience methods that helps building responses. -Check [documentation](../actix_web/dev/struct.HttpResponseBuilder.html) -for type descriptions. The methods `.body`, `.finish`, `.json` finalize response creation and -return a constructed *HttpResponse* instance. If this methods is called for the same +which implements various convenience methods for building responses. + +> Check the [documentation](../actix_web/dev/struct.HttpResponseBuilder.html) +> for type descriptions. + +The methods `.body`, `.finish`, and `.json` finalize response creation and +return a constructed *HttpResponse* instance. If this methods is called on the same builder instance multiple times, the builder will panic. ```rust @@ -26,22 +29,24 @@ fn index(req: HttpRequest) -> HttpResponse { ## Content encoding -Actix automatically *compresses*/*decompresses* payloads. Following codecs are supported: +Actix automatically *compresses*/*decompresses* payloads. The following codecs are supported: - * Brotli - * Gzip - * Deflate - * Identity +* Brotli +* Gzip +* Deflate +* Identity - If request headers contain a `Content-Encoding` header, the request payload is decompressed - according to the header value. Multiple codecs are not supported, i.e: `Content-Encoding: br, gzip`. +If request headers contain a `Content-Encoding` header, the request payload is decompressed +according to the header value. Multiple codecs are not supported, i.e: `Content-Encoding: br, gzip`. Response payload is compressed based on the *content_encoding* parameter. -By default `ContentEncoding::Auto` is used. If `ContentEncoding::Auto` is selected -then compression depends on the request's `Accept-Encoding` header. -`ContentEncoding::Identity` can be used to disable compression. -If another content encoding is selected the compression is enforced for this codec. For example, -to enable `brotli` use `ContentEncoding::Br`: +By default, `ContentEncoding::Auto` is used. If `ContentEncoding::Auto` is selected, +then the compression depends on the request's `Accept-Encoding` header. + +> `ContentEncoding::Identity` can be used to disable compression. +> If another content encoding is selected, the compression is enforced for that codec. + +For example, to enable `brotli` use `ContentEncoding::Br`: ```rust # extern crate actix_web; @@ -55,15 +60,14 @@ fn index(req: HttpRequest) -> HttpResponse { # fn main() {} ``` - ## JSON Request There are several options for json body deserialization. -The first option is to use *Json* extractor. You define handler function -that accepts `Json` as a parameter and use `.with()` method for registering +The first option is to use *Json* extractor. First, you define a handler function +that accepts `Json` as a parameter, then, you use the `.with()` method for registering this handler. It is also possible to accept arbitrary valid json object by -using `serde_json::Value` as a type `T` +using `serde_json::Value` as a type `T`. ```rust # extern crate actix_web; @@ -87,7 +91,7 @@ fn main() { } ``` -The second option is to use *HttpResponse::json()*. This method returns a +Another option is to use *HttpResponse::json()*. This method returns a [*JsonBody*](../actix_web/dev/struct.JsonBody.html) object which resolves into the deserialized value. @@ -116,8 +120,9 @@ fn index(mut req: HttpRequest) -> Box> { # fn main() {} ``` -Or you can manually load the payload into memory and then deserialize it. -Here is a simple example. We will deserialize a *MyObj* struct. We need to load the request +You may also manually load the payload into memory and then deserialize it. + +In the following example, we will deserialize a *MyObj* struct. We need to load the request body first and then deserialize the json into an object. ```rust @@ -149,15 +154,14 @@ fn index(req: HttpRequest) -> Box> { # fn main() {} ``` -A complete example for both options is available in -[examples directory](https://github.com/actix/actix-web/tree/master/examples/json/). - +> A complete example for both options is available in +> [examples directory](https://github.com/actix/actix-web/tree/master/examples/json/). ## JSON Response The `Json` type allows to respond with well-formed JSON data: simply return a value of -type Json where T is the type of a structure to serialize into *JSON*. The -type `T` must implement the `Serialize` trait from *serde*. +type Json where `T` is the type of a structure to serialize into *JSON*. +The type `T` must implement the `Serialize` trait from *serde*. ```rust # extern crate actix_web; @@ -184,14 +188,14 @@ fn main() { Actix automatically decodes *chunked* encoding. `HttpRequest::payload()` already contains the decoded byte stream. If the request payload is compressed with one of the supported -compression codecs (br, gzip, deflate) the byte stream is decompressed. +compression codecs (br, gzip, deflate), then the byte stream is decompressed. -Chunked encoding on response can be enabled with `HttpResponseBuilder::chunked()`. -But this takes effect only for `Body::Streaming(BodyStream)` or `Body::StreamingContext` bodies. -Also if response payload compression is enabled and streaming body is used, chunked encoding +Chunked encoding on a response can be enabled with `HttpResponseBuilder::chunked()`. +This takes effect only for `Body::Streaming(BodyStream)` or `Body::StreamingContext` bodies. +If the response payload compression is enabled and a streaming body is used, chunked encoding is enabled automatically. -Enabling chunked encoding for *HTTP/2.0* responses is forbidden. +> Enabling chunked encoding for *HTTP/2.0* responses is forbidden. ```rust # extern crate bytes; @@ -214,11 +218,11 @@ fn index(req: HttpRequest) -> HttpResponse { Actix provides multipart stream support. [*Multipart*](../actix_web/multipart/struct.Multipart.html) is implemented as -a stream of multipart items, each item can be a +a stream of multipart items. Each item can be a [*Field*](../actix_web/multipart/struct.Field.html) or a nested *Multipart* stream. `HttpResponse::multipart()` returns the *Multipart* stream for the current request. -In simple form multipart stream handling can be implemented similar to this example +The following demonstrates multipart stream handling for a simple form: ```rust,ignore # extern crate actix_web; @@ -248,17 +252,18 @@ fn index(req: HttpRequest) -> Box> { } ``` -A full example is available in the -[examples directory](https://github.com/actix/actix-web/tree/master/examples/multipart/). +> A full example is available in the +> [examples directory](https://github.com/actix/actix-web/tree/master/examples/multipart/). ## Urlencoded body Actix provides support for *application/x-www-form-urlencoded* encoded bodies. `HttpResponse::urlencoded()` returns a [*UrlEncoded*](../actix_web/dev/struct.UrlEncoded.html) future, which resolves -to the deserialized instance, the type of the instance must implement the -`Deserialize` trait from *serde*. The *UrlEncoded* future can resolve into -a error in several cases: +to the deserialized instance. The type of the instance must implement the +`Deserialize` trait from *serde*. + +The *UrlEncoded* future can resolve into an error in several cases: * content type is not `application/x-www-form-urlencoded` * transfer encoding is `chunked`. @@ -294,7 +299,7 @@ fn index(mut req: HttpRequest) -> Box> { *HttpRequest* is a stream of `Bytes` objects. It can be used to read the request body payload. -In this example handle reads the request payload chunk by chunk and prints every chunk. +In the following example, we read and print the request payload chunk by chunk: ```rust # extern crate actix_web; diff --git a/guide/src/qs_8.md b/guide/src/qs_8.md index 380f9e0e..f80fb8eb 100644 --- a/guide/src/qs_8.md +++ b/guide/src/qs_8.md @@ -5,9 +5,9 @@ integration tests. ## Unit tests -For unit testing actix provides a request builder type and simple handler runner. +For unit testing, actix provides a request builder type and a simple handler runner. [*TestRequest*](../actix_web/test/struct.TestRequest.html) implements a builder-like pattern. -You can generate a `HttpRequest` instance with `finish()` or you can +You can generate a `HttpRequest` instance with `finish()`, or you can run your handler with `run()` or `run_async()`. ```rust @@ -36,19 +36,20 @@ fn main() { } ``` - ## Integration tests -There are several methods how you can test your application. Actix provides -[*TestServer*](../actix_web/test/struct.TestServer.html) -server that can be used to run the whole application of just specific handlers -in real http server. *TestServer::get()*, *TestServer::post()* or *TestServer::client()* +There are several methods for testing your application. Actix provides +[*TestServer*](../actix_web/test/struct.TestServer.html), which can be used +to run the application with specific handlers in a real http server. + +`TestServer::get()`, `TestServer::post()`, and `TestServer::client()` methods can be used to send requests to the test server. -In simple form *TestServer* can be configured to use handler. *TestServer::new* method -accepts configuration function, only argument for this function is *test application* -instance. You can check the [api documentation](../actix_web/test/struct.TestApp.html) -for more information. +A simple form `TestServer` can be configured to use a handler. +`TestServer::new` method accepts a configuration function, and the only argument +for this function is a *test application* instance. + +> Check the [api documentation](../actix_web/test/struct.TestApp.html) for more information. ```rust # extern crate actix_web; @@ -70,8 +71,8 @@ fn main() { } ``` -The other option is to use an application factory. In this case you need to pass the factory -function same way as you would for real http server configuration. +The other option is to use an application factory. In this case, you need to pass the factory +function the same way as you would for real http server configuration. ```rust # extern crate actix_web; @@ -98,11 +99,10 @@ fn main() { } ``` -If you need more complex application configuration, for example you may need to -initialize application state or start `SyncActor`'s for diesel interation, you -can use `TestServer::build_with_state()` method. This method accepts closure -that has to construct application state. This closure runs when actix system is -configured already, so you can initialize any additional actors. +If you need more complex application configuration, use the `TestServer::build_with_state()` +method. For example, you may need to initialize application state or start `SyncActor`'s for diesel +interation. This method accepts a closure that constructs the application state, +and it runs when the actix system is configured. Thus, you can initialize any additional actors. ```rust,ignore #[test] @@ -127,13 +127,13 @@ fn test() { ## WebSocket server tests -It is possible to register a *handler* with `TestApp::handler()` that -initiates a web socket connection. *TestServer* provides `ws()` which connects to +It is possible to register a *handler* with `TestApp::handler()`, which +initiates a web socket connection. *TestServer* provides the method `ws()`, which connects to the websocket server and returns ws reader and writer objects. *TestServer* also -provides an `execute()` method which runs future objects to completion and returns +provides an `execute()` method, which runs future objects to completion and returns result of the future computation. -Here is a simple example that shows how to test server websocket handler. +The following example demonstrates how to test a websocket handler: ```rust # extern crate actix; diff --git a/guide/src/qs_9.md b/guide/src/qs_9.md index 158ba251..e0d71f12 100644 --- a/guide/src/qs_9.md +++ b/guide/src/qs_9.md @@ -3,10 +3,10 @@ Actix supports WebSockets out-of-the-box. It is possible to convert a request's `Payload` to a stream of [*ws::Message*](../actix_web/ws/enum.Message.html) with a [*ws::WsStream*](../actix_web/ws/struct.WsStream.html) and then use stream -combinators to handle actual messages. But it is simpler to handle websocket communications +combinators to handle actual messages, but it is simpler to handle websocket communications with an http actor. -This is example of a simple websocket echo server: +The following is an example of a simple websocket echo server: ```rust # extern crate actix; @@ -41,8 +41,8 @@ fn main() { } ``` -A simple websocket echo server example is available in the -[examples directory](https://github.com/actix/actix-web/blob/master/examples/websocket). +> A simple websocket echo server example is available in the +> [examples directory](https://github.com/actix/actix-web/blob/master/examples/websocket). -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/) +> 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/)