Repository: tokio-rs/axum
File: axum/src/extract/matched_path.rs (Rust)

Code before:
/// use axum::{
///     Router,
///     extract::MatchedPath,
///     http::Request,
///     routing::get,
/// };
/// use tower_http::trace::TraceLayer;
///
/// let app = Router::new()
///     .route("/users/:id", get(|| async { /* ... */ }))
///     .layer(
///         TraceLayer::new_for_http().make_span_with(|req: &Request<_>| {
///             let path = if let Some(path) = req.extensions().get::<MatchedPath>() {
///                 path.as_str()
///             } else {
///                 req.uri().path()
///             };
///             tracing::info_span!("http-request", %path)
///         }),
///     );
/// # let _: Router = app;
/// ```
///
/// # Matched path in nested routers
///
/// Because of how [nesting] works `MatchedPath` isn't accessible in middleware on nested routes:
///
/// ```
/// use axum::{
///     Router,
///     RequestExt,
///     routing::get,
///     extract::{MatchedPath, rejection::MatchedPathRejection},
///     middleware::map_request,
///     http::Request,
///     body::Body,
/// };
///
/// async fn access_matched_path(mut request: Request<Body>) -> Request<Body> {
///     // if `/foo/bar` is called this will be `Err(_)` since that matches
///     // a nested route
///     let matched_path: Result<MatchedPath, MatchedPathRejection> =
///         request.extract_parts::<MatchedPath>().await;
///
///     request
/// }
///
/// // `MatchedPath` is always accessible on handlers regardless
/// // if its for a nested route or not
/// async fn handler(matched_path: MatchedPath) {}
///

Review comment (suggestion):
```suggestion
/// Because of how [nesting] works, `MatchedPath` isn't accessible in middleware on nested routes:
```

Code after:
/// use axum::{
///     Router,
///     extract::MatchedPath,
///     http::Request,
///     routing::get,
/// };
/// use tower_http::trace::TraceLayer;
///
/// let app = Router::new()
///     .route("/users/:id", get(|| async { /* ... */ }))
///     .layer(
///         TraceLayer::new_for_http().make_span_with(|req: &Request<_>| {
///             let path = if let Some(path) = req.extensions().get::<MatchedPath>() {
///                 path.as_str()
///             } else {
///                 req.uri().path()
///             };
///             tracing::info_span!("http-request", %path)
///         }),
///     );
/// # let _: Router = app;
/// ```
///
/// # Matched path in nested routers
///
/// Because of how [nesting] works `MatchedPath` isn't accessible in middleware on nested routes:
///
/// ```
/// use axum::{
///     Router,
///     RequestExt,
///     routing::get,
///     extract::{MatchedPath, rejection::MatchedPathRejection},
///     middleware::map_request,
///     http::Request,
///     body::Body,
/// };
///
/// async fn access_matched_path(mut request: Request<Body>) -> Request<Body> {
///     // if `/foo/bar` is called this will be `Err(_)` since that matches
///     // a nested route
///     let matched_path: Result<MatchedPath, MatchedPathRejection> =
///         request.extract_parts::<MatchedPath>().await;
///
///     request
/// }
///
/// // `MatchedPath` is always accessible on handlers added via `Router::route`
/// async fn handler(matched_path: MatchedPath) {}
///
/// let app = Router::new()