Skip to content

hierarchical route definitions  #812

@tj

Description

@tj

I refuse to do this until I'm happy with how you define such a thing, but it would be useful for cutting down boilerplate code and everything we have now could be built on top of this, so I'm going to start brainstorming here :).

While what we have right now is not really an issue, one might typically do something like the following:

app.all('/admin/*', ensure.loggedIn, ensure.role('admin'), accessLogger);
app.get('/admin', admin.show);
app.get('/admin/stats', stats.load, stats.json);

Internally this would be easier to manage with the following representation, but useful as a public API as well.

app
  .get('/admin')
  .use(ensure.loggedIn)
  .use(ensure.role('admin'))
  .use(accessLogger)
  .end(admin.show)
  .get('/stats')
    .use(stats.load)
    .end(stats.json)
  .get('/users')
    .use(users.load)
    .end(users.show)
    .get('/:id')
      .use(user.get)
      .end(user.show);

I can see this getting out of hand quite quickly though, and if users dont abstract out the callbacks to some other file and try to define them inline along with .get() / .use() etc it will look like hell. Another problem is that for an API like above, without having an explicit zero-arg .end() like jQuery we need an explicit end-point callback, though we can treat it as middleware internally. This method might look like this:

   .end = function(fn){
     this.use(fn);
     return this.pop();
   }

with this change the param callbacks could easily be normalized as well:

app.param(':uid', loadUser);
app.get('/user/:uid', callback);

internal representation:

app
  .get('/user/:uid')
  .use(loadUser)
  .end(callback)

and:

app.param(':uid', user.load);
app.param(':pid', post.load);
app.get('/user/:uid', user.show);
app.get('/user/:uid/post/:pid', post.show);
app.del('/user/:uid/post/:pid', post.destroy);

would be equivalent to:

app
  .get('/user/:uid')
  .use(user.load)
  .end(user.show)
  .get('/post/:pid')
    .use(post.load)
    .end(post.show)
    .del()
      .end(post.destroy);

we could go further and take .del(callback) etc to be equivalent to .del().end(callback).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions