在 rust/axum 中带或不带尾部斜线的路由路径

apo*_*hor 7 rust rust-axum

我想将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)

caf*_*e25 8

来自以下文档Router::layer

\n
\n

使用此方法添加的中间件将在路由之后运行,因此不能用于重写请求 URI。有关更多详细信息和解决方法,请参阅\xe2\x80\x9c 在 middleware\xe2\x80\x9d 中重写请求 URI 。

\n
\n
\n

解决方法是将中间件包裹在整个 Router 周围(这是有效的,因为 Router 实现了 Service):

\n
\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}\n
Run Code Online (Sandbox Code Playgroud)\n