You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何含内部异步调用的Axum通用路由无法编译?

通用Axum API路由适配自定义Handler的编译错误解决

我正在构建一个通用Axum API,想要让路由适配任意自定义Handler实现,但代码编译失败,报错信息如下:

原代码

use std::marker::PhantomData;
use std::sync::Arc;
use axum::extract::State;
use axum::Router;
use axum::routing::get;
use tokio::sync::Mutex;

trait Handler{
    async fn handle(&mut self);
}

struct GenericRouter<Backend, Handler>{
    _marker: PhantomData<(Backend, Handler)>
}

struct AxumBackend;

impl<H> GenericRouter<AxumBackend, H>
where
    H: Handler + Send + 'static,
{
    async fn route(state: State<Arc<Mutex<H>>>) {
        let mut state = state.lock().await;

        state.handle().await;
    }

    fn build(&self, handler: H) -> Router {
        let shared_state = Arc::new(Mutex::new(handler));

        Router::new()
            .route("/", get(Self::route))
            .with_state(shared_state)
    }
}

编译错误

error[E0277]: the trait bound `fn(axum::extract::State<Arc<tokio::sync::Mutex<H>>>) -> impl Future<Output = ()> {GenericRouter::<reproducable_example::AxumBackend, H>::route}: axum::handler::Handler<_, _>` is not satisfied
   --> src/reproducable_example.rs:34:29
    |
34  |             .route("/", get(Self::route))
    |                         --- ^^^^^^^^^^^ the trait `axum::handler::Handler<_, _>` is not implemented for fn item `fn(State<Arc<Mutex<H>>>) -> impl Future<Output = ()> {GenericRouter::<AxumBackend, H>::route}`
    |                         |
    |                         required by a bound introduced by this call
    |
    = help: the following other types implement trait `axum::handler::Handler<T, S>`:
              `Layered<L, H, T, S>` implements `axum::handler::Handler<T, S>`
              `MethodRouter<S>` implements `axum::handler::Handler<(), S>`
note: required by a bound in `axum::routing::get`

    |
385 | top_level_handler_fn!(get, GET);
    | ^^^^^^^^^^^^^^^^^^^^^^---^^^^^^
    | |                     |
    | |                     required by a bound in this function
    | required by this bound in `get`
    = note: this error originates in the macro `top_level_handler_fn` (in Nightly builds, run with -Z macro-backtrace for more info)

注释掉state.handle().await;代码后即可正常编译,说明问题不在函数签名或trait绑定上。


问题原因

Axum的Handler trait要求handler函数返回的future必须满足Send约束(Axum会在多线程运行时调度这些future)。而自定义的Handler trait中,async fn handle(&mut self)返回的future默认没有Send标注,导致调用state.handle().await后,整个route函数返回的future不满足Send,进而无法实现Axum的Handler trait。

解决方案

给自定义Handler trait的handle方法返回的future加上Send约束,确保所有实现该trait的类型返回的future都是可发送的。

修改后的代码:

use std::marker::PhantomData;
use std::sync::Arc;
use axum::extract::State;
use axum::Router;
use axum::routing::get;
use tokio::sync::Mutex;
// 导入Future trait以标注约束
use std::future::Future;

trait Handler{
    // 为返回的Future添加Send约束
    fn handle(&mut self) -> impl Future<Output = ()> + Send;
}

struct GenericRouter<Backend, Handler>{
    _marker: PhantomData<(Backend, Handler)>
}

struct AxumBackend;

impl<H> GenericRouter<AxumBackend, H>
where
    H: Handler + Send + 'static,
{
    async fn route(state: State<Arc<Mutex<H>>>) {
        let mut state = state.lock().await;

        state.handle().await;
    }

    fn build(&self, handler: H) -> Router {
        let shared_state = Arc::new(Mutex::new(handler));

        Router::new()
            .route("/", get(Self::route))
            .with_state(shared_state)
    }
}

说明

通过显式标注impl Future<Output = ()> + Send,强制所有Handler实现的handle方法返回可发送的future,这样route函数返回的future就满足了Axum对Handler trait的要求,编译即可通过。

内容的提问来源于stack exchange,提问作者Furkan Guvenc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 11:48:11