Skip to content

Commit

Permalink
Change Router::nest to flatten the routes (#1711)
Browse files Browse the repository at this point in the history
Co-authored-by: Jonas Platte <[email protected]>
  • Loading branch information
davidpdrsn and jplatte authored Apr 11, 2023
1 parent 14d2b2d commit 2c2cf36
Show file tree
Hide file tree
Showing 11 changed files with 694 additions and 391 deletions.
5 changes: 5 additions & 0 deletions axum/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

# Unreleased

- **fixed:** Fixed performance regression with `Router::nest` introduced in
0.6.0. `nest` now flattens the routes which performs better ([#1711])
- **fixed:** Extracting `MatchedPath` in nested handlers now gives the full
matched path, including the nested path ([#1711])
- **added:** Implement `Deref` and `DerefMut` for built-in extractors ([#1922])

[#1711]: https://github.com/tokio-rs/axum/pull/1711
[#1922]: https://github.com/tokio-rs/axum/pull/1922

# 0.6.12 (22. March, 2023)
Expand Down
19 changes: 0 additions & 19 deletions axum/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,6 @@ where
into_route: |handler, state| Route::new(Handler::with_state(handler, state)),
}))
}

pub(crate) fn from_router(router: Router<S, B>) -> Self
where
B: HttpBody + Send + 'static,
S: Clone + Send + Sync + 'static,
{
Self(Box::new(MakeErasedRouter {
router,
into_route: |router, state| Route::new(router.with_state(state)),
}))
}

pub(crate) fn call_with_state(
self,
request: Request<B>,
state: S,
) -> RouteFuture<B, Infallible> {
self.0.call_with_state(request, state)
}
}

impl<S, B, E> BoxedIntoRoute<S, B, E> {
Expand Down
39 changes: 38 additions & 1 deletion axum/src/extract/matched_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,26 @@ mod tests {
req
}

let app = Router::new()
.nest_service("/:a", Router::new().route("/:b", get(|| async move {})))
.layer(map_request(extract_matched_path));

let client = TestClient::new(app);

let res = client.get("/foo/bar").send().await;
assert_eq!(res.status(), StatusCode::OK);
}

#[crate::test]
async fn can_extract_nested_matched_path_in_middleware_using_nest() {
async fn extract_matched_path<B>(
matched_path: Option<MatchedPath>,
req: Request<B>,
) -> Request<B> {
assert_eq!(matched_path.unwrap().as_str(), "/:a/:b");
req
}

let app = Router::new()
.nest("/:a", Router::new().route("/:b", get(|| async move {})))
.layer(map_request(extract_matched_path));
Expand All @@ -253,7 +273,7 @@ mod tests {
}

let app = Router::new()
.nest("/:a", Router::new().route("/:b", get(|| async move {})))
.nest_service("/:a", Router::new().route("/:b", get(|| async move {})))
.layer(map_request(assert_no_matched_path));

let client = TestClient::new(app);
Expand All @@ -262,6 +282,23 @@ mod tests {
assert_eq!(res.status(), StatusCode::OK);
}

#[tokio::test]
async fn can_extract_nested_matched_path_in_middleware_via_extension_using_nest() {
async fn assert_matched_path<B>(req: Request<B>) -> Request<B> {
assert!(req.extensions().get::<MatchedPath>().is_some());
req
}

let app = Router::new()
.nest("/:a", Router::new().route("/:b", get(|| async move {})))
.layer(map_request(assert_matched_path));

let client = TestClient::new(app);

let res = client.get("/foo/bar").send().await;
assert_eq!(res.status(), StatusCode::OK);
}

#[crate::test]
async fn can_extract_nested_matched_path_in_middleware_on_nested_router() {
async fn extract_matched_path<B>(matched_path: MatchedPath, req: Request<B>) -> Request<B> {
Expand Down
Loading

0 comments on commit 2c2cf36

Please sign in to comment.