Axum中Fallback路由无法获取Extension中间件的问题解决
问题原因
你在fallback中单独创建了一个带有独立State的子Router,这个子Router没有应用主Router的route_layer中间件。当请求走到fallback路由时,info_middleware并未执行,也就没有插入MyConnectionInfo扩展,导致处理器因找不到该扩展抛出500错误。
解决方案
方案一:复用主Router的State与中间件(推荐)
修改fallback的定义,去掉单独的with_state调用,让它直接共享主Router的全局State和中间件:
let app = axum::Router::new() .route("/", get(home_get)) .nest_service("/assets", get_service(ServeDir::new(Path::new("assets")))) .fallback(get(home_get)) // 移除此处的.with_state(state.clone()) .route_layer(axum::middleware::from_fn_with_state(state.clone(), info_middleware)) .with_state(state);
主Router的route_layer会作用于所有已定义的路由(包括fallback),同时全局with_state设置的State会被fallback的处理器共享。请求经过fallback时会先执行info_middleware插入扩展,处理器就能正常获取Extension<MyConnectionInfo>。
方案二:给fallback单独添加中间件(不推荐,冗余)
如果需要给fallback设置独立逻辑,可以在fallback的子Router上重复添加中间件,但会造成代码冗余,仅适用于特殊场景:
let app = axum::Router::new() .route("/", get(home_get)) .nest_service("/assets", get_service(ServeDir::new(Path::new("assets")))) .fallback( get(home_get) .with_state(state.clone()) .route_layer(axum::middleware::from_fn_with_state(state.clone(), info_middleware)) ) .route_layer(axum::middleware::from_fn_with_state(state.clone(), info_middleware)) .with_state(state);
额外说明
- axum的Router链式调用中,后续添加的
route_layer会作用于之前所有已定义的路由(包括fallback),只要fallback未被封装为独立子Router,就能共享全局中间件。 - 全局
with_state设置的State会被所有路由的处理器共享,无需在每个路由(包括fallback)中单独指定。
内容的提问来源于stack exchange,提问作者sudoExclamationExclamation
相关产品推荐
相关产品推荐

