Skip to content
New issue

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

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

Already on GitHub? # 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 👍

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

No branches or pull requests

3 participants