from_fn
#
- Be an
async fn
.
- Take one or more extractors as the first arguments.
- Take
Next<B>
as the final argument.
- Return something that implements
IntoResponse
.
async fn my_middleware<B>(
request: Request<B>, // extractors*
next: Next<B>, // 最后一个参数必须是 next
) -> Response { // 返回 IntoResponse
// request 相关
// ...
// 调用下游 next
let response = next.run(request).await;
// response 相关
// ...
// 返回response
response
}
let app = Router::new()
.route("/", get(|| async { "Hello, world!" }))
.layer(middleware::from_fn(my_middleware));
async fn auth<B>(
TypedHeader(auth): TypedHeader<Authorization<Bearer>>,
request: Request<B>,
next: Next<B>, // the last: `next`
) -> Result<Response, StatusCode> {
if token_is_valid(auth.token()) {
let response = next.run(request).await;
Ok(response)
} else {
Err(StatusCode::UNAUTHORIZED)
}
}
fn token_is_valid(token: &str) -> bool {
// ...
}
let app = Router::new()
.route("/", get(|| async { /* ... */ }))
.route_layer(middleware::from_fn(auth));
from_fn_with_state
#
#[derive(Clone)]
struct AppState { /* ... */ }
async fn my_middleware<B>(
State(state): State<AppState>,
// you can add more extractors here but the last
// extractor must implement `FromRequest` which
// `Request` does
request: Request<B>,
next: Next<B>,
) -> Response {
// do something with `request`...
let response = next.run(request).await;
// do something with `response`...
response
}
let state = AppState { /* ... */ };
let app = Router::new()
.route("/", get(|| async { /* ... */ }))
.route_layer(middleware::from_fn_with_state(state.clone(), my_middleware))
.with_state(state);