How to create a fn middleware based on first route parameter while ignore rest route parameters? #2315
-
In my example, there are follow routes:
All data are stored as state in a structure of As almost all routes contains pub async fn workspace_middleware<B>(
State(store): State<ServerStore>,
Path(ws): Path<String>,
mut req: Request<B>,
next: Next<B>,
) -> Result<Response, StatusCode> {
if let Some(workspace) = store.read().await.get(&ws) {
req.extensions_mut().insert(workspace.clone());
Ok(next.run(req).await)
} else {
Err(StatusCode::NOT_FOUND)
}
} And register the routes and middleware in main function like: let store = Arc::new(RwLock::new(HashMap::new()));
let workspace_rt = Router::new()
.route("/stacks", get(read_stacks))
.nest("/stacks/:stack_id", get(read_stack))
.route_layer(middleware::from_fn_with_state(
store.clone(),
workspace_middleware,
))
.route("/", post(create_workspace))
let router = Router::new()
.nest("/ws/:ws_id", workspace_rt)
.with_state(store); It works fine on
If define middlware function parameters in follow pattern: pub async fn workspace_middleware<B>(
State(store): State<ServerStore>,
Path((ws, _)): Path<(String, Option<usize>)>,
mut req: Request<B>,
next: Next<B>,
) -> Result<Response, StatusCode> It works with
I have tried to fix this problem by changing type of the second route parameter declared in the tuple from Is it impossible to implement this middleware with a function? or I could get route parameters in another way in the function? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
I think the easiest way is to define a struct with the params you want: #[tokio::main]
async fn main() {
let app = Router::new()
.route("/:a", get(handler_a))
.route("/:a/:b", get(handler_b));
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
}
#[derive(Debug, Deserialize)]
struct Params {
// this field name must correspond to the path param (`:a`)
// params with other names will be ignored by `Path`
a: String,
}
async fn handler_a(Path(params): Path<Params>) {
dbg!(params);
}
async fn handler_b(Path(params): Path<Params>) {
dbg!(params);
} But you can also extract |
Beta Was this translation helpful? Give feedback.
I think the easiest way is to define a struct with the params you want:
But you can also extract
P…