Handlers 处理程序

Request Handlers 请求处理程序

request handler(请求处理程序)是一个async function(异步函数),它接受零个或多个可以从请求中提取的参数(即impl FromRequest),并返回可以转换为HttpResponse的类型(即impl Responder)。

请求处理分为两个阶段。 首先,调用handler对象,返回实现Responder特性的任何对象。 然后,在返回的对象上调用respond_to(),将其自身转换为HttpResponseError

默认情况下,actix-web为某些标准类型(例如&'static str, String等)提供Responder实现。

有关implementations的完整列表,请查看Responder 文档

有效处理程序的示例:

async fn index(_req: HttpRequest) -> &'static str {
    "Hello world!"
}
async fn index(_req: HttpRequest) -> String {
    "Hello world!".to_owned()
}

您还可以将签名更改为return impl Responder,如果涉及到更复杂的类型,它可以很好地工作。

async fn index(_req: HttpRequest) -> impl Responder {
    Bytes::from_static(b"Hello world!")
}
async fn index(req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> {
    ...
}

自定义类型的Response

要直接从handler函数返回自定义类型,该类型需要实现Responder特性。

让我们为自定义类型创建一个response(响应),该response序列化为application/json response:

use actix_web::{Error, HttpRequest, HttpResponse, Responder};
use serde::Serialize;
use futures::future::{ready, Ready};

#[derive(Serialize)]
struct MyObj {
    name: &'static str,
}

// Responder
impl Responder for MyObj {
    type Error = Error;
    type Future = Ready<Result<HttpResponse, Error>>;

    fn respond_to(self, _req: &HttpRequest) -> Self::Future {
        let body = serde_json::to_string(&self).unwrap();

        // Create response and set content type
        ready(Ok(HttpResponse::Ok()
            .content_type("application/json")
            .body(body)))
    }
}

async fn index() -> impl Responder {
    MyObj { name: "user" }
}

Streaming response body 流式响应体

Response body(响应体)可以异步生成。 在这种情况下,body必须实现stream特征Stream<Item=Bytes, Error=Error>,即:

use actix_web::{web, App, HttpServer, Error, HttpResponse};
use bytes::Bytes;
use futures::stream::once;
use futures::future::ok;

async fn index() -> HttpResponse {
    let body = once(ok::<_, Error>(Bytes::from_static(b"test")));

    HttpResponse::Ok()
        .content_type("application/json")
        .streaming(body)
}

#[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()
        .await
}

不同的return类型(任一种)

有时,您需要返回不同类型的responses。 例如,您可以进行错误检查并返回错误,返回异步responses或需要两种不同类型的任何结果。

在这种情况下,可以使用Either类型。 可以将两种不同的responder(响应者)类型组合为一个类型。

use actix_web::{Either, Error, HttpResponse};

type RegisterResult = Either<HttpResponse, Result<&'static str, Error>>;

fn index() -> RegisterResult {
    if is_a_variant() {
        // <- choose variant A
        Either::A(HttpResponse::BadRequest().body("Bad data"))
    } else {
        // <- variant B
        Either::B(Ok("Hello!"))
    }
}
接下来: 提取器