Extract seperate Path parameters in middleware and handler #3249
-
SummaryWith the following routing .merge(Router::new()
.route("accounts/{account_id}/invites/{invite_id}",delete(accounts::remove_invite))
.route_layer(axum::middleware::from_fn_with_state(pool.clone(),accounts::account_admin))
) How can I extract the account_id for my middleware and the invite_id for my handler? The middleware should not be aware of any additional route parameters beyond the first one for the account_id. However, the route handler can collect all the parameters if needed. pub async fn account_admin(Path(account_id): Path<i64>,State(pool): State<Pool<Sqlite>>, req: Request, next: Next) -> Result<Response, StatusCode> {
let user = req.extensions().get::<User>().unwrap();
match sqlx::query!("SELECT role FROM account_users WHERE account_id = ? AND user_id = ?", account_id, user.id)
.fetch_one(&pool).await {
Ok(result)=>{
if result.role!="admin".to_string() {
return Err(StatusCode::UNAUTHORIZED)
}
},
Err(_) => {
return Err(StatusCode::UNAUTHORIZED)
}
};
Ok(next.run(req).await)
}
pub async fn remove_invite(Path(invite_id): Path<i64>,State(pool): State<Pool<Sqlite>>) -> StatusCode {
sqlx::query!("DELETE FROM account_invites WHERE id = ?", invite_id)
.execute(&pool).await.unwrap();
StatusCode::OK
} Right now, no matter what I tried, I was getting
Although I have not tested with lower axum versions, it does appear that my current code (with adjusting the handler accordingly) would have worked before 0.8. This is based on #2930 axum version0.8.1 |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
You can use |
Beta Was this translation helpful? Give feedback.
-
You can do it like this: use serde::Deserialize;
#[derive(Deserialize)]
struct MiddlewarePath {
account_id: i64,
}
#[derive(Deserialize)]
struct HandlerPath {
invite_id: i64,
}
pub async fn account_admin(
Path(MiddlewarePath { account_id }): Path<MiddlewarePath>,
State(pool): State<Pool<Sqlite>>,
req: Request,
next: Next,
) -> Result<Response, StatusCode> {
// ...
}
pub async fn remove_invite(
Path(HandlerPath { invite_id }): Path<HandlerPath>,
State(pool): State<Pool<Sqlite>>,
) -> StatusCode {
// ...
} |
Beta Was this translation helpful? Give feedback.
You can do it like this: