请求处理是一个异步函数,该函数接受零个或多个可以从请求中提取的参数(即impl FromRequest),并返回可以转换为HttpResponse的类型(即impl Responder)。
请求处理分为两个阶段。首先,调用处理程序对象,返回实现Responder特质的任何对象。然后,在返回的对象上调用respond_to(),将其自身转换为HttpResponseor 或 Error。
默认情况下kayrx::web提供了一些标准类型的Responder实现,诸如&'static str,String等
有关实现的完整列表,请参阅Responder文档。
有效的处理程序示例:
async fn index(_req: HttpRequest) -> &'static str {
"Hello world!"
}
async fn index2(_req: HttpRequest) -> String {
"Hello world!".to_owned()
}
您还可以将返回签名更改为 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>> {
...
}
要直接从处理函数返回自定义类型,该类型需要实现Responder特质.
让我们为序列化为application/json的响应创建一个自定义类型:
use kayrx::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" }
}
响应主体(Response body)可以异步生成。在这种情况下,body必须实现stream 特质 即: Stream<Item=Bytes, Error=Error>.
use kayrx::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)
}
#\[kayrx::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| App::new().route("/async", web::to(index)))
.bind("127.0.0.1:8088")?
.run()
.await
}
有时,您需要返回不同类型的响应。例如,您可以进行错误检查并返回错误,返回异步响应或需要两种不同类型的任何结果。
在这种情况下,可以使用Either类型。 Either允许将两种不同的响应者类型组合为一个类型.
use kayrx::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!"))
}
}
[set title Kayrx / doc / handler]
[set doc-section basic-handler]
[stash doc-content][require raw ../_side.html]