-
SummaryHi. I want to rewrite URI for sub-router. For example I have some api routes which can return .json or .xml format, and by default I have json. So my routers can looks like:
I want to rewrite last two routes to pass pub type Dict = HashMap<String, String>;
fn ext_to_qs<B>(mut req: Request<B>) -> Request<B> {
let uri = req.uri().to_string();
let re = Regex::new(r"^([^?]+?)(?:\.(xml|json))(\?.*)?$").unwrap();
if let Some(caps) = re.captures(&uri) {
let new_path = caps.get(1).unwrap().as_str().to_string();
let ext = caps.get(2).unwrap().as_str();
let new_query = match req.uri().query() {
Some(existing_query) => format!("{}&format={}", existing_query, ext),
None => format!("format={}", ext),
};
let new_uri = format!("{}?{}", new_path, new_query);
*req.uri_mut() = new_uri.parse().unwrap();
}
req
}
fn handler(Path(name): Path<String>, Query(qs): Query<Dict>
) -> impl IntoResponse {
println!(">> kind: {:?}, name: {}, qs: {:?}", kind, name, qs); // name still have ext, format added to qs
println!(">> req: {:?}", req.uri()); // path without .ext here
"hello".into_response()
} In docs I found this guide to apply the layer around the whole let pages = Router::new()
.route("/api/{name}", get(handler)) // and more api endpoinds
.route("/", get(pages::index)); // and more page endpoinds
let middleware = tower::util::MapRequestLayer::new(ext_to_qs);
let app_with_middleware = middleware.layer(app);
let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await.unwrap();
axum::serve(listener, app_with_middleware.into_make_service()).await.unwrap(); But it not working if I want split apis and pages routes (like I want to rewrite path only for apis routes): let pages = Router::new().route("/", get(pages::index));
let apis: Router<()> = Router::new().route("/api/{name}", get(handler));
let middleware = tower::util::MapRequestLayer::new(ext_to_qs);
let apis_with_muddleware = middleware.layer(apis);
let app: Router<()> = Router::new()
.merge(pages) // ok
.merge(apis_with_muddleware); // some long error here
// or: .merge(apis_with_muddleware.into());
let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await.unwrap();
axum::serve(listener, app.into_make_service()).await.unwrap(); So final question is it possible to rewrite URI only for part of routes (sub-router), in order to extractors also respect to it? axum version0.8.1 |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
You can |
Beta Was this translation helpful? Give feedback.
If you want to rewrite the URL in this way, yeah.
Or you can rewrite the URL globally if that's something you're ok with.