iron / router

Router middleware for the Iron web framework.
165 stars 74 forks source link

Stacked Routes #99

Closed MichaelHirn closed 9 years ago

MichaelHirn commented 9 years ago

I am working with iron to build a JSON-API. The idea is to have one API struct that puts the different namespaces upon the root URL /api, which would then allow to seperate the different namespaces in their own files. e.g.

let mut router = Router::new();
router.get("/api/", namespace1());
router.get("/api/", namespace2());

fn namespace1() -> Router {
    let mut router = Router::new();
    router.get("namespace1", some_fn);
    router.post("namespace1", some_post_fn);
    router;
}

My expectation was, that after a call to /api/namespace1 the result from some_fn get's returned. I could not get it to work though. I think that makes some sense as Router has already the Handler trait implemented and it would allow for the creation of bigger applications.

leoyvens commented 9 years ago

If I understand correctly, don't you want a /api/:namespace route which would then return the appropriate router for the given namespace? In your example, a call to /api/namespace1 is a 404 because the route /api/ will only match exactly /api/.

MichaelHirn commented 9 years ago

I get your thought process, I would need to check if it works completely with placeholders, befor I can give a valueable answer.
One more example, though coming from the react-router.

<Router>
    <Route path="/" component={App}>
      <Route path="about" component={About}/>
      <Route path="users" component={Users}>
        <Route path="/user/:userId" component={User}/>
      </Route>
      <Route path="*" component={NoMatch}/>
    </Route>
  </Router>
reem commented 9 years ago

@MichaelHirn you should be using mount for this, not router - your initial snipper would be written like:

let mut mount = Mount::new();
mount.mount("/api/", namespace1());
mount.mount("/api/", namespace2());

fn namespace1() -> Router {
    let mut router = Router::new();
    router.get("namespace1", some_fn);
    router.post("namespace1", some_post_fn);
    router
}

and it would work as you described

MichaelHirn commented 9 years ago

@reem Perfect, mount is exactly what I was looking for.