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

如何在Axum中同时使用axum::extract::Query与axum::extract::State?

解决Axum中同时使用State与Query提取器的编译错误

问题根源

编译失败的核心原因是枚举MyParams的serde反序列化 trait 拼写错误,同时需确保类型满足Query提取器的要求:

  • serde::Deserialze 应为 serde::Deserialize(少了一个r)
  • Query提取器要求目标类型实现serde::Deserialize<'de>,需保证derive宏正确生成代码

修正步骤

  1. 修复serde依赖配置
    确保Cargo.toml中serde启用derive特性:

    [dependencies]
    axum = "0.7"
    serde = { version = "1.0", features = ["derive"] }
    tokio = { version = "1.0", features = ["full"] }
    
  2. 修正MyParams的derive宏
    修正拼写错误并移除无关trait(ValueEnum是clap命令行参数解析用的,和HTTP查询参数提取无关):

    #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
    pub enum MyParams {
        Normal,
        Verbose,
    }
    
  3. 确保处理器函数的提取器导入正确
    处理器需导入Axum的State和Query提取器:

    use axum::{extract::{State, Query}, Json, StatusCode};
    use std::sync::Arc;
    
    async fn path(
        State(middle_ware): State<Arc<MyState>>,
        params: Query<MyParams>
    ) -> impl IntoResponse {
        println!("{:?}", params);
        let result = middle_ware.process().await;
        (StatusCode::OK, Json(result))
    }
    

完整可运行代码示例

use axum::{
    extract::{State, Query},
    Json, Router, Server,
};
use serde::{Deserialize, Serialize};
use std::net::SocketAddr;
use std::sync::Arc;

#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum MyParams {
    Normal,
    Verbose,
}

#[derive(Debug)]
pub struct MyState {
    port: u16,
}

impl MyState {
    pub async fn process(&self) -> String {
        format!("Processing on port {}", self.port)
    }
}

impl MyState {
    pub async fn serve(self) {
        let port = self.port;
        let app = Router::new()
            .route("/path", axum::routing::get(path))
            .with_state(Arc::new(self));

        let addr = SocketAddr::from(([127, 0, 0, 1], port));
        Server::bind(&addr)
            .serve(app.into_make_service())
            .await
            .unwrap();
    }
}

async fn path(
    State(middle_ware): State<Arc<MyState>>,
    params: Query<MyParams>
) -> impl IntoResponse {
    println!("{:?}", params);
    let result = middle_ware.process().await;
    (StatusCode::OK, Json(result))
}

验证方式

启动服务后,访问http://localhost:指定端口/path?MyParams=Normal或http://localhost:指定端口/path?MyParams=Verbose,即可正常提取查询参数与状态。

内容的提问来源于stack exchange,提问作者Finlay Weber

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 00:05:33