Handle trailing slashes for Axum routes
After migrating my site from Bridgetown to Axum/Maud, I noticed that trailing slashes in an URL would result in a 404. They are not optional like with many other frameworks.
In order to fix this we need to use an middleware from the tower-http crate, which will rewrite/normalize the url.
Installation
The tower-http crate exposes functionality by using feature flags, in order to use the "Normalize Path" feature, we need to enable it:
# Cargo.toml tower-http = { version = "*", features = ["normalize-path"] } tower-layer = "*"
We also need tower-layer
for reasons I'll explain later.
Usage
When I first tried to use the library, I got very confused, as you'll have to wrap your entire router with this Tower layer, and not just use it like any other layer.
This didn't work for me:
let router = Router::new() .nest("/api", api::routes()) .layer(NormalizePathLayer::trim_trailing_slash());
While this did work:
let router = Router::new() .nest("/api", api::routes()); let app = NormalizePathLayer::trim_trailing_slash().layer(router);
This has to do with the fact that layers run after routing, so the trailing slash has to be removed before the routing happens:
Middleware added with
Router::layer
will run after routing. That means it cannot be used to run middleware that rewrites the request URI. By the time the middleware runs the routing is already done.
The tower-layer
crate I mentioned before is needed for the trait to wrap the NormalizePathLayer
around your router.