krakenjs / express-enrouten

An express route initialization and configuration module.
Other
172 stars 38 forks source link

Router level middleware #66

Open hunterc opened 9 years ago

hunterc commented 9 years ago

I might be missing something, but is there currently a way to pass middleware to be used for every request that enrouten makes a route for?

lmarkus commented 9 years ago

That's actually the default behavior. Any particular issue you're running into?

hunterc commented 9 years ago

So I'm using enrouten to generate controller type routes:

var router = enrouten({
    directory: 'controllers',
    index: 'controllers/home'
});

I want to require authentication on all of these routes:

router.use(authenticateMiddleware);

That doesn't seem to be working because the routes are going to be ahead of the middleware. Am I missing something?

Also what do you mean by that's the default behavior?

lmarkus commented 9 years ago

Oops, Apologies. I got this mixed up with another repo. was replying in the context of a Kraken application (Which uses meddleware for applying middleware to all defined routes).

Let me compose a better response in a bit.

hunterc commented 9 years ago

I just noticed that my first comment was worded terribly. Your answer now makes sense. Let me rephrase my question. I have used enrouten to generate my routes. I want to mount that in my express app for all my routing. Before I mount it I want to add some logging / auth / etc to the returned app.

jasisk commented 9 years ago
  var router = enrouten({
    directory: 'controllers',
    index: 'controllers/home'
});

express-enrouten returns a middleware-ish object. It's middleware-ish because you register it in your app like a middleware, but it isn't really a middleware. Additionally worth pointing out, in your case, it's also not a router. It's a clever little pattern we use to get access to your app instance without you having to explicitly pass it to us.

In reality, we create a router inside express-enrouten, and mount it (app.use) into your app instance ourselves.

Currently, we don't expose that router externally which means there is no easy way to register middleware against it, specifically. There are some ways you could hack around it but I wouldn't recommend any of them. If, however, it fits your needs, you could always preempt express-enrouten with other middleware that apply to every route:

app.use(authenticationMiddleware, enrouten(opts));

All that said, I think it's an interesting idea worth exploring so I'm gonna keep this issue open.

hunterc commented 9 years ago

@jasisk thanks for the response. I think it would really useful to be able to add an additional config option to add middleware that get set before routes are set:

var router = enrouten({
    directory: 'controllers',
    index: 'controllers/home',
    middleware: [middleware1, middleware2, ...etc]
});
jasisk commented 9 years ago

I think it would really useful to be able to add an additional config option to add middleware that get set before routes are set

I like the thought. I can certainly see the value if you're using multiple instances of express-enrouten, mounting multiple app instances, etc.

For what it's worth, as Lenny mentioned we tend to use meddleware preferring to have a central location for managing middleware. It's certainly not without its tradeoffs—flattening the route map isn't great—but it's worked well for the 90% case.

betweenbrain commented 8 years ago

Just curious, is there any issue with doing something like the following to address this issue

app.use(
    function (req, res, next) {
        console.log('Time:', Date.now());
        next();
    },
    enrouten({
       directory: 'controllers',
       index: 'controllers/home'
    })
);
pradeep-tiwari commented 7 years ago

I was wondering if this issue answers my curiosity for registering router level middlewares in KrakenJS as pointed on the documentation page of ExpressJS link

dsaraswati commented 7 years ago

@pradeep-tiwari Reference /lib/directory.js:69
enrouten calls the exported method with express's Router object. So we have access to all the default functionalities that Express provides with its router. Here is a sample code:

module.exports = function(router) {
    router.use(function(req, res, next) {
        console.log('routelevel middleware called for ' + req.baseUrl);
        next();
    });
    router.get('/', function(req, res) {
      // do something on this route
    })
}

Hope that helps.

pradeep-tiwari commented 7 years ago

Yup, that's it. Thanks.