我想将http://0.0.0.0/foo和路由http://0.0.0.0/foo/到同一个get_foo处理程序。然而,实际上,只有/foo路由和/foo/404。我怀疑我设置/附加的中间件错误:
use axum::http::StatusCode;
use axum::{routing::{get}, Router};
use std::{net::SocketAddr};
use tower_http::normalize_path::NormalizePathLayer;
#[tokio::main]
async fn main() {
let app = Router::new()
.route("/foo", get(get_foo))
.layer(NormalizePathLayer::trim_trailing_slash());
let port_str = std::env::var("PORT").unwrap_or("8000".to_owned());
let port = port_str.parse::<u16>().unwrap();
let addr = SocketAddr::from(([0, 0, 0, 0], port));
println!("listening on http://{}", addr);
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
async fn get_foo() -> Result<String, StatusCode> {
Ok("Hello from foo.".to_owned())
}
Run Code Online (Sandbox Code Playgroud)
...以及随附的Cargo.toml:
[package]
name = "axum_trailing_slash"
version = "0.1.0"
edition = "2021"
[dependencies]
axum = { version = "0.6" }
tokio = { version = "1.0", features = ["full"] }
tower = { version = "0.4" }
tower-http = { version = "0.3", features = ["normalize-path"] }
Run Code Online (Sandbox Code Playgroud)
来自以下文档Router::layer:
\n\n使用此方法添加的中间件将在路由之后运行,因此不能用于重写请求 URI。有关更多详细信息和解决方法,请参阅\xe2\x80\x9c 在 middleware\xe2\x80\x9d 中重写请求 URI 。
\n
\n\n解决方法是将中间件包裹在整个 Router 周围(这是有效的,因为 Router 实现了 Service):
\n
//\xe2\x80\xa6\nuse axum::ServiceExt;\nuse tower::layer::Layer;\n\n#[tokio::main]\nasync fn main() {\n let app =\n NormalizePathLayer::trim_trailing_slash().layer(Router::new().route("/foo", get(get_foo)));\n //\xe2\x80\xa6\n}\nRun Code Online (Sandbox Code Playgroud)\n