# Middleware
Middleware in Actix Web is a layer that wraps around a Service. It allows you to inspect, modify, or reject requests before they reach your handler, and similarly modify responses before they are sent back to the client.
##Built-in Middleware
Actix Web provides several essential middlewares out of the box:
- Logger: Logs request metadata (requires env_logger or similar).
- Compress: Automatically compresses HTTP responses based on client headers.
- NormalizePath: Normalizes trailing slashes.
- Condition: Conditionally enables other middleware.
use actix_web::{middleware::Logger, App, HttpServer};
#[actix_web::main]
async fn main() -> std::io::Result<()> {
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
HttpServer::new(|| {
App::new()
// Wrap the app with the Logger middleware
.wrap(Logger::default())
// ... routes
})
.bind("127.0.0.1:8080")?
.run()
.await
}##Creating Custom Middleware
Creating custom middleware requires implementing the Service and Transform traits. This can be complex because it involves generic types and futures.
For simpler use cases, Actix Web 4 introduced actix_web::middleware::from_fn, allowing you to write middleware as a simple async function!
use actix_web::{dev::{ServiceRequest, ServiceResponse}, Error, middleware::Next};
async fn my_middleware(
req: ServiceRequest,
next: Next<impl actix_web::body::MessageBody>,
) -> Result<ServiceResponse<impl actix_web::body::MessageBody>, Error> {
// Pre-processing: before handler is called
println!("Request made to: {}", req.path());
// Call the next service in the chain (the handler)
let res = next.call(req).await?;
// Post-processing: after handler returns
println!("Response status: {}", res.status());
Ok(res)
}
// Applying it:
// App::new().wrap(actix_web::middleware::from_fn(my_middleware))This functional approach drastically lowers the barrier to entry for adding custom authentication checks, rate limiting, or custom logging.