typestar

Middleware layers in Rust

A layer wraps every route below it: logging, timeouts, compression.

use std::time::Instant;

use axum::extract::Request;
use axum::middleware::{self, Next};
use axum::response::Response;
use axum::{routing::get, Router};

async fn timing(request: Request, next: Next) -> Response {
    let method = request.method().clone();
    let path = request.uri().path().to_string();
    let started = Instant::now();

    let response = next.run(request).await;

    println!("{method} {path} -> {} in {:?}", response.status(),
             started.elapsed());
    response
}

#[tokio::main]
async fn main() {
    let app = Router::new()
        .route("/", get(|| async { "ok" }))
        .layer(middleware::from_fn(timing));

    let listener = tokio::net::TcpListener::bind("127.0.0.1:8080")
        .await
        .unwrap();
    axum::serve(listener, app).await.unwrap();
}

How it works

  1. layer applies a tower service to the whole router.
  2. middleware::from_fn turns an async fn into a layer.
  3. Layers run outermost first, in reverse of the order added.

Keywords and builtins used here

The run, in numbers

Lines
30
Characters to type
719
Tokens
217
Three-star pace
110 tpm

At the three-star pace of 110 tokens a minute, this run takes about 118 seconds.

Type this snippet

Step 3 of 3 in Responses & middleware, step 8 of 9 in Web services with axum.

← Previous Next →