Expand description

Async functions that can be used to handle requests.

In axum a “handler” is an async function that accepts zero or more “extractors” as arguments and returns something that can be converted into a response.

Handlers are where your application logic lives and axum applications are built by routing between handlers.

Some examples of handlers:

use axum::{body::Bytes, http::StatusCode};

// Handler that immediately returns an empty `200 OK` response.
async fn unit_handler() {}

// Handler that immediately returns an empty `200 OK` response with a plain
// text body.
async fn string_handler() -> String {
    "Hello, World!".to_string()
}

// Handler that buffers the request body and returns it.
//
// This works because `Bytes` implements `FromRequest`
// and therefore can be used as an extractor.
//
// `String` and `StatusCode` both implement `IntoResponse` and
// therefore `Result<String, StatusCode>` also implements `IntoResponse`
async fn echo(body: Bytes) -> Result<String, StatusCode> {
    if let Ok(string) = String::from_utf8(body.to_vec()) {
        Ok(string)
    } else {
        Err(StatusCode::BAD_REQUEST)
    }
}

Instead of a direct StatusCode, it makes sense to use intermediate error type that can ultimately be converted to Response. This allows using ? operator in handlers. See those examples:

§Debugging handler type errors

For a function to be used as a handler it must implement the Handler trait. axum provides blanket implementations for functions that:

  • Are async fns.
  • Take no more than 16 arguments that all implement Send.
  • Returns something that implements IntoResponse.
  • If a closure is used it must implement Clone + Send and be 'static.
  • Returns a future that is Send. The most common way to accidentally make a future !Send is to hold a !Send type across an await.

Unfortunately Rust gives poor error messages if you try to use a function that doesn’t quite match what’s required by Handler.

You might get an error like this:

error[E0277]: the trait bound `fn(bool) -> impl Future {handler}: Handler<_, _>` is not satisfied
   --> src/main.rs:13:44
    |
13  |     let app = Router::new().route("/", get(handler));
    |                                            ^^^^^^^ the trait `Handler<_, _>` is not implemented for `fn(bool) -> impl Future {handler}`
    |
   ::: axum/src/handler/mod.rs:116:8
    |
116 |     H: Handler<T, B>,
    |        ------------- required by this bound in `axum::routing::get`

This error doesn’t tell you why your function doesn’t implement Handler. It’s possible to improve the error with the debug_handler proc-macro from the axum-macros crate.

Modules§

Structs§

Traits§