Question: In and out middleware
tgandrews opened this issue · comments
I may have misinterpreted middleware, but it seems that it only supports middleware that responds to requests. I was looking at creating a simple request timing middleware that would wrap all requests and log out the time for the request to execute.
I'm a complete rust newbie so I'm probably doing something wrong, but was looking to write something as below.
fn timer<'mw>(request: &mut Request, response: &mut Response) -> MiddlewareResult<'mw> {
let before = time::precise_time_ns();
let path = request.path_without_query().unwrap();
let method = request.origin.method.to_string();
response.next_middleware();
let after = time::precise_time_ns();
let duration = after - before;
println!("{} {} took {}ns", method, path, duration)
}
We don't have great support for this but it should be possible to do what you want:
You can implement a middleware which wraps a handler, similar to mount and just wrap the middleware.invoke(..)
with your timing code.
You can probably do this more lightweight within a middleware!()
by capturing another handler, but it might have some typeinference quirks, but it would look something like this:
let inner = middleware!(....); // or router, etc
server.utilize(middleware!(|req, res| {
let before = ..;
let result = inner.invoke(req, res);
let duration = ...;
println!(...);
return result // return is required here as it short circuits the macro to return the correct type
});
related issue: #20
Since this appears possible if a bit clunky, I'm going to close this issue.