跳到主要内容

axum::handler模块

什么是Handler

用于处理请求异步函数

在axum中,处理程序是一个异步函数,它接受零个或多个提取器作为参数, 并返回可以转换为响应的内容

处理程序应用程序逻辑所在的地方axum应用程序通过处理程序之间的路由构建的

即是说,处理程序是axum应用程序的核心, 路由是程序的入口,整个axum应用程序是由路由和处理程序组成的。

一些handlers的示例

use axum::{body::Bytes, http::StatusCode};

// 立即返回空的`200 OK`响应
async fn unit_handler() {}

// 立即返回空的`200 OK`响应并附带纯文本主体的处理程序。
async fn string_handler() -> String {
"Hello, World!".to_string()
}

// 处理程序将缓冲请求正文并返回它。
// 这是因为 `Bytes` 实现了 `FromRequest`,所以可以用作提取器。
// `String` 和 `StatusCode` 都实现了 `IntoResponse`,因此 `Result<String, StatusCode>` 也实现了 `IntoResponse`
aysnc fn echo(body: Bytes) -> Result<String, StatusCode> {
if let Ok(string) = String::from_utf8(body.to_vec()) {
Ok(string)
} else {
Err(StatusCode::BAD_REQUEST)
}
}

与其直接使用 StatusCode ,使用最终可以转换为 Response 的中间错误类型更合理。 这样可以在处理程序中使用 ? 运算符。

看看这些示例:

处理处理程序类型错误

要将函数用作处理程序,它必须实现 Handler 特性

axum 为具有以下功能提供了概括实现:

  • async fn s。

  • 最多不超过16个参数,所有参数都实现Send

    • 除最后一个参数外,所有参数都实现FromRequestParts
    • 最后一个参数实现FromRequest
  • 返回实现了IntoResponse的内容。

  • 如果使用闭包,它必须实现Clone + Send并且是'static

  • 返回一个Sendfuture。意外使future !Send的最常见方式是在等待期间保存一个!Send类型。

不幸的是,如果您尝试使用与处理程序所需不完全匹配的函数,Rust会给出糟糕的错误消息。

您可能会收到类似这样的错误:

error[E0277]: the trait bound `fn(bool) -> impl Future {handler}: Handler<_, _>` is not satisfied
--> src/main.rs:13:44
|
13 | let app = Router::new().route("/", get(handler));
| ^^^^^^^ the trait `Handler<_, _>` is not implemented for `fn(bool) -> impl Future {handler}`
|
::: axum/src/handler/mod.rs:116:8
|
116 | H: Handler<T, B>,
| ------------- required by this bound in `axum::routing::get`

这个错误没有告诉您为什么您的函数没有实现Handler

可以使用axum-macros crate 中的debug_handler 过程宏来改进错误

模块

  • future: Handler future types

结构体

  • HandlerService: 将Handler适配为Service的适配器。
  • Layered: 通过应用 Tower 中间件从处理程序创建的服务(Service)。

Traits

  • Handler: 可用于处理请求的异步函数的特性。
  • HandlerWithoutStateExt: 没有状态的 Handler 的扩展特性。