How to create (and type) higher-order handlers? #517
-
I want to create handlers to return responses from specific structs in my code (using String as an example): fn create_handler(s: String) -> ??? {
// handler
|| async move {
s
}
}
let app = Router::new()
.route("/", get(create_struct_handler())); However, the return type of this function is unclear to me. I found a similar question on higher-order async closures but that seems to erase the argument being passed to the closure it wraps. All in all, I'm wondering if there is a cleaner or perhaps there is a more axum/tower-idiomatic way to accomplish my goal? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Yep! You can do this: use axum::{Router, body::Body, handler::Handler, http::HeaderMap, routing::get};
use std::net::SocketAddr;
#[tokio::main]
async fn main() {
let app = Router::new()
.route("/", get(create_handler("foo".to_string())))
.route("/foo", get(create_handler_with_extractor("foo".to_string())))
.route("/bar", get(create_handler_with_extractors("foo".to_string())));
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
fn create_handler(s: String) -> impl Handler<Body, ()> {
|| async move {
s
}
}
fn create_handler_with_extractor(s: String) -> impl Handler<Body, (String,)> {
|body| async move {
format!("{} {}", s, body)
}
}
fn create_handler_with_extractors(s: String) -> impl Handler<Body, (HeaderMap, String)> {
|headers, body| async move {
format!("{:?} {} {}", headers, s, body)
}
} It'll become slightly easier in 0.4 thanks to #502. I generally would recommend passing config to handlers via |
Beta Was this translation helpful? Give feedback.
Yep! You can do this: