#[middleware_fn]Expand description
Attribute macro for defining middleware functions with automatic signature injection.
This macro eliminates boilerplate by automatically providing req, res, and ctx parameters
to your middleware function. It transforms a simple function into a proper Feather middleware.
§What This Macro Does
The #[middleware_fn] macro injects three parameters into your function:
req: &mut Request- The HTTP requestres: &mut Response- The HTTP responsectx: &AppContext- Application context for accessing state
Your function must return Outcome (which is Result<MiddlewareResult, Box<dyn Error>>).
§Basic Example
ⓘ
use feather::middleware_fn;
#[middleware_fn]
fn log_requests() {
println!("{} {}", req.method, req.uri);
next!()
}
app.use_middleware(log_requests);§With Route Handlers
ⓘ
use feather::{App, middleware_fn};
#[middleware_fn]
fn greet() {
let name = req.param("name").unwrap_or("Guest".to_string());
res.send_text(format!("Hello, {}!", name));
next!()
}
let mut app = App::new();
app.get("/greet/:name", greet);§Compared to the middleware! Macro
Both #[middleware_fn] and middleware! work similarly, but #[middleware_fn] is
best for reusable, named middleware functions, while middleware! is best for inline closures:
ⓘ
// Using #[middleware_fn] - for reusable middleware
#[middleware_fn]
fn validate_auth() {
if !req.headers.contains_key("Authorization") {
res.set_status(401);
res.send_text("Unauthorized");
return next!();
}
next!()
}
app.use_middleware(validate_auth);
// Using middleware! - for inline middleware
app.get("/", middleware!(|_req, res, _ctx| {
res.send_text("Hello!");
next!()
}));§Accessing Application State
ⓘ
use feather::{State, middleware_fn};
#[derive(Clone)]
struct Config {
api_key: String,
}
#[middleware_fn]
fn check_api_key() {
let config = ctx.get_state::<State<Config>>();
let is_valid = config.with_scope(|cfg| cfg.api_key == "secret");
if !is_valid {
res.set_status(403);
res.send_text("Forbidden");
return next!();
}
next!()
}§Error Handling
ⓘ
use feather::middleware_fn;
#[middleware_fn]
fn parse_json() {
if let Ok(body) = String::from_utf8(req.body.clone()) {
// Process body
next!()
} else {
res.set_status(400);
res.send_text("Invalid UTF-8");
next!()
}
}§See Also
- Use
#[jwt_required]together with#[middleware_fn]for JWT-protected routes - See the Middlewares Guide for more patterns