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

Mount and other middleware's, how to chain them? #81

Open
GildedHonour opened this issue Apr 30, 2016 · 2 comments
Open

Mount and other middleware's, how to chain them? #81

GildedHonour opened this issue Apr 30, 2016 · 2 comments

Comments

@GildedHonour
Copy link

GildedHonour commented Apr 30, 2016

It doesn't support Chain, right? So there's no way to do this or something like this?

  env_logger::init().unwrap();
  let mut hbse = HandlebarsEngine::new();
  hbse.add(Box::new(DirectorySource::new("./views/", ".hbs")));
  if let Err(r) = hbse.reload() {
    panic!("{}", r.description());
  }

  let mut router = Router::new();
  router.get("/", index);

  let mut chain = Chain::new(router);
  chain.link_after(hbse);

  let mut mount = Mount::new();
  mount
    .mount("/", router)
    .mount("/css/", Static::new(Path::new("static/css/")))
    .mount("/js/", Static::new(Path::new("static/js/")))
    .mount("/img/", Static::new(Path::new("static/img/")));

  chain.link_after(mount); // --- compile error

  println!("Server running at http://localhost:3000/");
  Iron::new(mount).http("localhost:3000").unwrap();

The error is:

 error: the trait `for<'r, 'r, 'r> core::ops::Fn<(&'r mut iron::request::Request<'r, 'r>, iron::response::Response)>` is not implemented for the type `mount::mount::Mount` [E0277]
src/main.rs:58   chain.link_after(mount);

Is other words, I want to get Mount to work with other middleware's. How can I do this?

@GildedHonour GildedHonour changed the title Mount and other middleware's Mount and other middleware's, how to chain them? Apr 30, 2016
@SkylerLipthay
Copy link
Member

SkylerLipthay commented May 1, 2016

Do you perhaps mean to do the following?

let mut chain = Chain::new(mount);
// ...
Iron::new(chain).http("localhost:3000").unwrap();

Chain is a Handler which wraps/decorates another Handler (in your initial code: router; here: mount) with any number of middleware. Ultimately Iron::new only accepts a single Handler.

To elaborate on middleware: BeforeMiddleware implementations accept and potentially modify a request before it reaches the Handler. AfterMiddleware implementations accept and potentially modify a response before it is finally sent to the HTTP client. AroundMiddleware implementations combine the functionality of BeforeMiddleware and AfterMiddleware.

@durango
Copy link

durango commented Nov 7, 2016

To elaborate for @GildedHonour I just recently did this for a project:

    // macro for Router
    let router = router!(
        home: get "/" => handle_request,
        dashboard: get "/dashboard" => with_middleware!(dashboard, [IsAuthenticated]),
        logout: get "/logout" => logout
    );

    let mut mount = Mount::new();
    mount.mount("/", router)
        .mount("/user/", models::user::router())
        .mount("/inventory/", models::inventory::router())
        // ... etc ....
        ;

    let mut chain = Chain::new(mount);
    chain.link_around(SessionStorage::new(SignedCookieBackend::new(my_secret)));

    chain.link_before(ErrorRecover);
    chain.link_after(ErrorRecover);

    let server = Iron::new(chain);
    server.http(host).unwrap();
// models/users.rs
pub fn router() -> Router {
    let mut router = Router::new();
    router.post("/", create, "create_user");

    router
}

I think the aim is to use only one mount variable for your application/the chain. Let me know if this is clear or not 👍

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