From 4dc1c93027011840d8f1909dd287d78068966828 Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Tue, 23 Aug 2022 18:56:24 +0200 Subject: [PATCH] Tweak `layer` and `route_layer` docs (#1307) --- axum/src/docs/method_routing/layer.md | 9 ++- axum/src/docs/method_routing/route_layer.md | 4 + axum/src/docs/routing/layer.md | 88 +++++++++------------ axum/src/docs/routing/route_layer.md | 4 + 4 files changed, 52 insertions(+), 53 deletions(-) diff --git a/axum/src/docs/method_routing/layer.md b/axum/src/docs/method_routing/layer.md index 10bde2abd0d..cdf6f93342a 100644 --- a/axum/src/docs/method_routing/layer.md +++ b/axum/src/docs/method_routing/layer.md @@ -1,11 +1,12 @@ -Apply a [`tower::Layer`] to the router. - -All requests to the router will be processed by the layer's -corresponding middleware. +Apply a [`tower::Layer`] to all routes in the router. This can be used to add additional processing to a request for a group of routes. +Note that the middleware is only applied to existing routes. So you have to +first add your routes (and / or fallback) and then call `layer` afterwards. Additional +routes added after `layer` is called will not have the middleware added. + Works similarly to [`Router::layer`](super::Router::layer). See that method for more details. diff --git a/axum/src/docs/method_routing/route_layer.md b/axum/src/docs/method_routing/route_layer.md index c2e2c0615c2..f8f17b9c6fd 100644 --- a/axum/src/docs/method_routing/route_layer.md +++ b/axum/src/docs/method_routing/route_layer.md @@ -1,6 +1,10 @@ Apply a [`tower::Layer`] to the router that will only run if the request matches a route. +Note that the middleware is only applied to existing routes. So you have to +first add your routes (and / or fallback) and then call `layer` afterwards. Additional +routes added after `layer` is called will not have the middleware added. + This works similarly to [`MethodRouter::layer`] except the middleware will only run if the request matches a route. This is useful for middleware that return early (such as authorization) which might otherwise convert a `405 Method Not Allowed` into a diff --git a/axum/src/docs/routing/layer.md b/axum/src/docs/routing/layer.md index f659babba43..1c029c7ff4d 100644 --- a/axum/src/docs/routing/layer.md +++ b/axum/src/docs/routing/layer.md @@ -1,69 +1,52 @@ -Apply a [`tower::Layer`] to the router. - -All requests to the router will be processed by the layer's -corresponding middleware. +Apply a [`tower::Layer`] to all routes in the router. This can be used to add additional processing to a request for a group of routes. -Note this differs from [`Handler::layer`](crate::handler::Handler::layer) -which adds a middleware to a single handler. +Note that the middleware is only applied to existing routes. So you have to +first add your routes (and / or fallback) and then call `layer` afterwards. Additional +routes added after `layer` is called will not have the middleware added. + +If you want to add middleware to a single handler you can either use +[`MethodRouter::layer`] or [`Handler::layer`]. # Example -Adding the [`tower::limit::ConcurrencyLimit`] middleware to a group of -routes can be done like so: +Adding the [`tower_http::trace::TraceLayer`]: ```rust -use axum::{ - routing::get, - Router, -}; -use tower::limit::{ConcurrencyLimitLayer, ConcurrencyLimit}; - -async fn first_handler() {} - -async fn second_handler() {} - -async fn third_handler() {} - -// All requests to `first_handler` and `second_handler` will be sent through -// `ConcurrencyLimit` -let app = Router::new().route("/", get(first_handler)) - .route("/foo", get(second_handler)) - .layer(ConcurrencyLimitLayer::new(64)) - // Request to `GET /bar` will go directly to `third_handler` and - // wont be sent through `ConcurrencyLimit` - .route("/bar", get(third_handler)); -# async { -# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap(); -# }; +use axum::{routing::get, Router}; +use tower_http::trace::TraceLayer; + +let app = Router::new() + .route("/foo", get(|| async {})) + .route("/bar", get(|| async {})) + .layer(TraceLayer::new_for_http()); +# let _: Router = app; ``` -This is commonly used to add middleware such as tracing/logging to your -entire app: +If you need to write your own middleware see ["Writing +middleware"](crate::middleware#writing-middleware) for the different options. -```rust -use axum::{ - routing::get, - Router, -}; -use tower_http::trace::TraceLayer; +If you only want middleware on some routes you can use [`Router::merge`]: -async fn first_handler() {} +```rust +use axum::{routing::get, Router}; +use tower_http::{trace::TraceLayer, compression::CompressionLayer}; -async fn second_handler() {} +let with_tracing = Router::new() + .route("/foo", get(|| async {})) + .layer(TraceLayer::new_for_http()); -async fn third_handler() {} +let with_compression = Router::new() + .route("/bar", get(|| async {})) + .layer(CompressionLayer::new()); +// Merge everything into one `Router` let app = Router::new() - .route("/", get(first_handler)) - .route("/foo", get(second_handler)) - .route("/bar", get(third_handler)) - .layer(TraceLayer::new_for_http()); -# async { -# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap(); -# }; + .merge(with_tracing) + .merge(with_compression); +# let _: Router = app; ``` # Multiple middleware @@ -71,6 +54,13 @@ let app = Router::new() It's recommended to use [`tower::ServiceBuilder`] when applying multiple middleware. See [`middleware`](crate::middleware) for more details. +# Runs after routing + +Middleware added with this method will run _after_ routing and thus cannot be +used to rewrite the request URI. See ["Rewriting request URI in +middleware"](crate::middleware#rewriting-request-uri-in-middleware) for more +details and a workaround. + # Error handling See [`middleware`](crate::middleware) for details on how error handling impacts diff --git a/axum/src/docs/routing/route_layer.md b/axum/src/docs/routing/route_layer.md index 58a42cd8f92..5aa0dec770b 100644 --- a/axum/src/docs/routing/route_layer.md +++ b/axum/src/docs/routing/route_layer.md @@ -1,6 +1,10 @@ Apply a [`tower::Layer`] to the router that will only run if the request matches a route. +Note that the middleware is only applied to existing routes. So you have to +first add your routes (and / or fallback) and then call `layer` afterwards. Additional +routes added after `layer` is called will not have the middleware added. + This works similarly to [`Router::layer`] except the middleware will only run if the request matches a route. This is useful for middleware that return early (such as authorization) which might otherwise convert a `404 Not Found` into a