From 4046b0b697074ef30ff7a830b4b33cb7e06ea8ae Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Thu, 2 Jan 2020 13:11:12 +0600 Subject: [PATCH] review handlers section --- content/docs/handlers.md | 31 ++++++--------------- examples/async-handlers/Cargo.toml | 9 +++--- examples/async-handlers/src/async_stream.rs | 28 ------------------- examples/async-handlers/src/main.rs | 29 +------------------ examples/async-handlers/src/stream.rs | 21 +++++++------- examples/either/src/main.rs | 14 +++------- 6 files changed, 28 insertions(+), 104 deletions(-) delete mode 100644 examples/async-handlers/src/async_stream.rs diff --git a/content/docs/handlers.md b/content/docs/handlers.md index 456271e..bd0b79c 100644 --- a/content/docs/handlers.md +++ b/content/docs/handlers.md @@ -6,12 +6,12 @@ weight: 160 # Request Handlers -A request handler is a function that accepts zero or more parameters that can be extracted +A request handler is an async function that accepts zero or more parameters that can be extracted from a request (ie, [*impl FromRequest*][implfromrequest]) and returns a type that can be converted into an HttpResponse (ie, [*impl Responder*][implresponder]). Request handling happens in two stages. First the handler object is called, returning any -object that implements the [*Responder*][respondertrait] trait. Then, `respond_to()` is +object that implements the [*Responder*][respondertrait] trait. Then, `respond_to()` is called on the returned object, converting itself to a `HttpResponse` or `Error`. By default actix-web provides `Responder` implementations for some standard types, @@ -22,13 +22,13 @@ such as `&'static str`, `String`, etc. Examples of valid handlers: ```rust -fn index(_req: HttpRequest) -> &'static str { +async fn index(_req: HttpRequest) -> &'static str { "Hello world!" } ``` ```rust -fn index(_req: HttpRequest) -> String { +async fn index(_req: HttpRequest) -> String { "Hello world!".to_owned() } ``` @@ -37,13 +37,13 @@ You can also change the signature to return `impl Responder` which works well if complex types are involved. ```rust -fn index(_req: HttpRequest) -> impl Responder { +async fn index(_req: HttpRequest) -> impl Responder { Bytes::from_static(b"Hello world!") } ``` ```rust -fn index(req: HttpRequest) -> Box> { +async fn index(req: HttpRequest) -> Box> { ... } ``` @@ -56,28 +56,13 @@ Let's create a response for a custom type that serializes to an `application/jso {{< include-example example="responder-trait" file="main.rs" section="responder-trait" >}} -## Async handlers +## Streaming response body -There are two different types of async handlers. Response objects can be generated asynchronously -or more precisely, any type that implements the [*Responder*][respondertrait] trait. - -In this case, the handler must return a `Future` object that resolves to the *Responder* type, i.e: - -{{< include-example example="async-handlers" file="main.rs" section="async-responder" >}} - -Or the response body can be generated asynchronously. In this case, body must implement +Response body can be generated asynchronously. In this case, body must implement the stream trait `Stream`, i.e: {{< include-example example="async-handlers" file="stream.rs" section="stream" >}} -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 future -that resolves to a `HttpResponse`. - -{{< include-example example="async-handlers" file="async_stream.rs" section="async-stream" >}} - ## Different return types (Either) Sometimes, you need to return different types of responses. For example, you can error diff --git a/examples/async-handlers/Cargo.toml b/examples/async-handlers/Cargo.toml index afdf0dc..c1e24a2 100644 --- a/examples/async-handlers/Cargo.toml +++ b/examples/async-handlers/Cargo.toml @@ -1,9 +1,10 @@ [package] name = "async-handlers" -version = "1.0.0" +version = "2.0.0" edition = "2018" [dependencies] -actix-web = "1.0" -futures = "0.1" -bytes = "0.4" +actix-web = "2.0" +actix-rt = "1.0" +futures = "0.3.1" +bytes = "0.5" diff --git a/examples/async-handlers/src/async_stream.rs b/examples/async-handlers/src/async_stream.rs deleted file mode 100644 index ddf41f4..0000000 --- a/examples/async-handlers/src/async_stream.rs +++ /dev/null @@ -1,28 +0,0 @@ -fn is_error() -> bool { - false -} - -// -use actix_web::{error, Error, HttpResponse}; -use futures::future::{result, Future}; - -fn index() -> Result>, Error> { - if is_error() { - Err(error::ErrorBadRequest("bad request")) - } else { - Ok(Box::new(result(Ok(HttpResponse::Ok() - .content_type("text/html") - .body("Hello!"))))) - } -} -// - -pub fn main() { - use actix_web::{web, App, HttpServer}; - - HttpServer::new(|| App::new().route("/", web::to_async(index))) - .bind("127.0.0.1:8088") - .unwrap() - .run() - .unwrap(); -} diff --git a/examples/async-handlers/src/main.rs b/examples/async-handlers/src/main.rs index ef4e1a5..59722fb 100644 --- a/examples/async-handlers/src/main.rs +++ b/examples/async-handlers/src/main.rs @@ -1,30 +1,3 @@ -pub mod async_stream; pub mod stream; -// -use actix_web::{Error, HttpResponse}; -use futures::future::{ok, Future}; -fn index() -> Box> { - Box::new(ok::<_, Error>( - HttpResponse::Ok().content_type("text/html").body("Hello!"), - )) -} - -fn index2() -> Box> { - Box::new(ok::<_, Error>("Welcome!")) -} - -fn main() { - use actix_web::{web, App, HttpServer}; - - HttpServer::new(|| { - App::new() - .route("/async", web::to_async(index)) - .route("/", web::to_async(index2)) - }) - .bind("127.0.0.1:8088") - .unwrap() - .run() - .unwrap(); -} -// +fn main() {} diff --git a/examples/async-handlers/src/stream.rs b/examples/async-handlers/src/stream.rs index 79424cd..3399f33 100644 --- a/examples/async-handlers/src/stream.rs +++ b/examples/async-handlers/src/stream.rs @@ -1,23 +1,22 @@ // -use actix_web::{Error, HttpResponse}; +use actix_web::{web, App, HttpServer, Error, HttpResponse}; use bytes::Bytes; use futures::stream::once; +use futures::future::ok; -fn index() -> HttpResponse { - let body = once::(Ok(Bytes::from_static(b"test"))); +async fn index() -> HttpResponse { + let body = once(ok::<_, Error>(Bytes::from_static(b"test"))); HttpResponse::Ok() .content_type("application/json") - .streaming(Box::new(body)) + .streaming(body) } -pub fn main() { - use actix_web::{web, App, HttpServer}; - - HttpServer::new(|| App::new().route("/async", web::to_async(index))) - .bind("127.0.0.1:8088") - .unwrap() +#[actix_rt::main] +async fn main() -> std::io::Result<()> { + HttpServer::new(|| App::new().route("/async", web::to(index))) + .bind("127.0.0.1:8088")? .run() - .unwrap(); + .await } // diff --git a/examples/either/src/main.rs b/examples/either/src/main.rs index 75837fe..ab5208c 100644 --- a/examples/either/src/main.rs +++ b/examples/either/src/main.rs @@ -1,23 +1,18 @@ // use actix_web::{Either, Error, HttpResponse}; -use futures::future::{ok, Future}; -type RegisterResult = - Either>>; +type RegisterResult = Either>; fn index() -> RegisterResult { if is_a_variant() { // <- choose variant A Either::A(HttpResponse::BadRequest().body("Bad data")) } else { - Either::B( - // <- variant B - Box::new(ok(HttpResponse::Ok() - .content_type("text/html") - .body("Hello!".to_string()))), - ) + // <- variant B + Either::B(Ok("Hello!")) } } +// fn main() { use actix_web::{web, App, HttpServer}; @@ -28,7 +23,6 @@ fn main() { .run() .unwrap(); } -// fn is_a_variant() -> bool { true