Skip to content

Commit

Permalink
Tweak layer and route_layer docs (#1307)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidpdrsn authored and jplatte committed Oct 19, 2022
1 parent af00053 commit 4dc1c93
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 53 deletions.
9 changes: 5 additions & 4 deletions 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.

Expand Down
4 changes: 4 additions & 0 deletions 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
Expand Down
88 changes: 39 additions & 49 deletions axum/src/docs/routing/layer.md
@@ -1,76 +1,66 @@
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

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
Expand Down
4 changes: 4 additions & 0 deletions 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
Expand Down

0 comments on commit 4dc1c93

Please sign in to comment.