Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use handler in impl #442

Open
imclint21 opened this issue Aug 23, 2019 · 6 comments
Open

How to use handler in impl #442

imclint21 opened this issue Aug 23, 2019 · 6 comments

Comments

@imclint21
Copy link

imclint21 commented Aug 23, 2019

Hi,

I would like to use a custom handler or a logger in the same impl, but i've this error:

44 |         server.utilize(self.logger);
   |                             ^^^^^^ help: use parentheses to call the method: `logger(...)

Thanks

@jolhoeft
Copy link
Member

The utilize method takes something implementing the Middleware trait. There is a blanket implementation for functions taking the request and response, and return a MiddlewareResult. There is also a fragile macro, but I recommend you avoid it. It has some unexpected behavior. I often end up just implementing the trait.

@amitavaghosh1
Copy link

@jolhoeft is the macro implementation still not recommended by you?

@jolhoeft
Copy link
Member

@amitavaghosh1 I am not sure. As I mentioned it's behavior is unexpected. I have nickel mostly migrated to async hyper (see the head of the master branch), and I think some sort of macro may be needed to fill some usability gaps. I'd be interested in hearing more about use cases.

@amitavaghosh1
Copy link

amitavaghosh1 commented Aug 18, 2021

for me the use case is not that complicated. a hypothetical similar situation would be. when the route is /internal add some headers, when its not remove any headers that might be associated with a /internal route.
so I guess there would be two ways of doing it.

One way is the form-data example, where there can be a struct as such:

struct InternalMiddleware { isInternal: bool }

and then have impl Middleware<()> for InternalMiddleware {...

the other way is something like:

fn add_header<D>(is_internal: bool) -> impl Middleware<D> {
    middleware! { |req, res|
        if is_internal {
            println!("internal");
            return res.next_middleware()
        }

        let auth_header = match req.origin.headers.get::<Authorization<Bearer>>() {
            Some(header) => header,
            None => panic!("No authorization header found")
        };

        let header = hyper::header::HeaderFormatter(auth_header).to_string();
        println!("Header v {}", header);
    }
}

since in rust we cannot return closures, this is one way I figured, with some help, this way without having to add a struct.
The other advantage of this would be that, I can pass a service to this wrapper function and then the middleware can run it. Right now most of the the routers I have tried, like tide, actix etc (actix is already difficult :D) doesn't allow this kind of thing. so the only way is to pass the database objects inside the state. And I don't think that is a very good way to go about it, in no way should a router be aware of the database in its state, it just makes testing very difficult and I think it also violates srp.

@jolhoeft
Copy link
Member

You're example is a good case of my problem with the middleware macro. The macro expects something implementing Responder, but res.next_middleware returns a MiddlewareResult, so the above code won't compile. Maybe we could implement Responder for MiddlewareResult. I think with these caveats, using the middleware macro is fine.

My other question is where you need this. For the 0.11.x branch, I'm not planning on anything but major bug fixes. Most of my limited time is on the master branch where I'm trying to get async fully functional.

@amitavaghosh1
Copy link

Since at my workplace, we will be mostly taking up rust for web dev, quite slowly and incrementally, we will mostly be using latest releases, so if you release this in one of your newer branches, it won't be a problem for us. I am also trying to learn the language, so that I can contribute.
Rust for web development, I think, still needs some work. There are a few minor things where I keep getting stuck at, and it gets harder each time to convince people to use it as well 😃 .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants