axum 0.3.1

Web framework that focuses on ergonomics and modularity
Documentation
Apply a [`tower::Layer`] to the router.

All requests to the router will be processed by the layer's
corresponding middleware.

This can be used to add additional processing to a request for a group
of routes.

Note this differs from [`handler::Layered`](crate::handler::Layered)
which adds a middleware to a single handler.

# Example

Adding the [`tower::limit::ConcurrencyLimit`] middleware to a group of
routes can be done like so:

```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 `handler` and `other_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();
# };
```

This is commonly used to add middleware such as tracing/logging to your
entire app:

```rust
use axum::{
    routing::get,
    Router,
};
use tower_http::trace::TraceLayer;

async fn first_handler() {}

async fn second_handler() {}

async fn third_handler() {}

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();
# };
```

# Applying multiple middleware

Its recommended to use [`tower::ServiceBuilder`] to apply multiple middleware at
once, instead of calling `layer` repeatedly:

```rust
use axum::{
    routing::get,
    AddExtensionLayer,
    Router,
};
use tower_http::{trace::TraceLayer};
use tower::{ServiceBuilder, limit::ConcurrencyLimitLayer};

async fn handler() {}

#[derive(Clone)]
struct State {}

let app = Router::new()
    .route("/", get(handler))
    .layer(
        ServiceBuilder::new()
            .layer(TraceLayer::new_for_http())
            .layer(ConcurrencyLimitLayer::new(64))
            .layer(AddExtensionLayer::new(State {}))
    );
# async {
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
# };
```

# Error handling

axum's error handling model requires handlers to always return a response.
However middleware is one possible way to introduce errors into an application.
If hyper receives an error the connection will be closed without sending a
response. Thus axum requires those errors to be handled gracefully:

```rust
use axum::{
    routing::get,
    error_handling::HandleErrorLayer,
    http::StatusCode,
    BoxError,
    Router,
};
use tower::{ServiceBuilder, timeout::TimeoutLayer};
use std::time::Duration;

async fn handler() {}

let app = Router::new()
    .route("/", get(handler))
    .layer(
        ServiceBuilder::new()
            // this middleware goes above `TimeoutLayer` because it will receive
            // errors returned by `TimeoutLayer`
            .layer(HandleErrorLayer::new(|_: BoxError| StatusCode::REQUEST_TIMEOUT))
            .layer(TimeoutLayer::new(Duration::from_secs(10)))
    );
# async {
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
# };
```

See [`error_handling`](crate::error_handling) for more details on axum's error
handling model.