rust 如何同时使用axum::extract::Query和axum::extract::State?

jk9hmnmh  于 2023-01-21  发布在  其他
关注(0)|答案(1)|浏览(207)

我正在构建一个处理程序,它需要注入状态,还需要提取查询参数。
我一开始只提取了状态,这就成功了,代码如下:

#[derive(ValueEnum, Clone, Debug, serde::Deserialze, serde::Serialize)]
    pub enum MyParams {
       Normal,
       Verbose,
    }

    #[derive(Debug)]
   pub struct MyState {
      port: u16,
   }
    
    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));
        axum::Server::bind(&addr)
            .serve(app.into_make_service())
            .await
            .unwrap();
    }

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

现在我想提取查询参数,所以我更新了代码如下:

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))
}

但这无法编译,错误为

|
24  |             .route("/path", axum::routing::get(path))
    |                                  ------------------ ^^^^^^^^^ the trait `Handler<_, _, _>` is not implemented for fn item `fn(State<Arc<MyState>>, Query<MyParams>) -> impl futures::Future<Output = impl IntoResponse> {path}`
    |                                  |
    |                                  required by a bound introduced by this call

有什么想法做什么,能够同时使用axum::extract::Query和axum::extract::State与Axum?

kxkpmulp

kxkpmulp1#

该文档提供了以下示例:
https://docs.rs/axum/latest/axum/extract/index.html#applying-multiple-extractors
PS:别忘了注意提取器的顺序。

use axum::{
    extract::{Path, Query},
    routing::get,
    Router,
};
use uuid::Uuid;
use serde::Deserialize;

let app = Router::new().route("/users/:id/things", get(get_user_things));

#[derive(Deserialize)]
struct Pagination {
    page: usize,
    per_page: usize,
}

impl Default for Pagination {
    fn default() -> Self {
        Self { page: 1, per_page: 30 }
    }
}

async fn get_user_things(
    Path(user_id): Path<Uuid>,
    pagination: Option<Query<Pagination>>,
) {
    let Query(pagination) = pagination.unwrap_or_default();

    // ...
}

相关问题