nickel-org / nickel.rs

An expressjs inspired web framework for Rust

Home Page:http://nickel-org.github.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.