Polka: Filtered middleware never run

Created on 11 Mar 2019  Â·  7Comments  Â·  Source: lukeed/polka

Hi there,

I'm trying to replace Express with Polka in a small project, and I'm facing an issue where a "filtered" middleware is never run :

const polka = require('polka');
const serveStatic = require('serve-static');

/*
 *
 */

const app = polka();

// Always run, as expected
app.use((req, res, next) => {
  console.log(req.method, req.url);
  next();
});

// Never run, but I expect it to be when navigating to /admin/**/*
app.use('/admin', (req, res, next) => {
  console.log('  @admin!');
  next();
});

// Always run, as expected
app.use(serveStatic(__dirname + '/_static'));

/*
 *
 */

app.listen(4444, () => console.log('Listening on port 4444...'));

It's probably a very silly error but I don't see what I'm doing wrong here.

question

All 7 comments

Hey~! So (current) Polka behaves differently than Express in that the "global middleware" (eg .use(foo)) will _always_ run before anything else, disregarding the order that the application was defined. This has been changed in next version Polka, which went out this weekend in preparation for the 1.0.

As an example, this may be happening in your app:

polka()
  .use((req, res, next) => {
    console.log('1st: ', req.method, req.url);
    next();
  })
  .use('/admin', (req, res, next) => {
    console.log('I will never run');
    next();
  })
  .use(serveStatic(__dirname + '/_static')) // 2nd
  .use((req, res, next) => {
    console.log('3rd – nothing will make it beyond this point');
    res.end('goodbye');
  })

So a curl localhost:4444/admin/foo will execute:

~> 1st: GET /admin/foo
~> (serveStatic)
~> 3rd – nothing will make it beyond this point

As you can tell, this turned out to be more of a problem for express ex-pats than I anticipated, hence the (breaking) change for Polka 1.0 😄

The relevant documentation for this current behavior is here: https://github.com/lukeed/polka#middleware-sequence

Although, I wouldn't get used to it 😉

Thanks for your quick answer!

Though I still don't understand why it's not working. In your example, navigating to /{APP}/users/123 will trigger the users "filtered" middleware that was registered for /users routes, right? So why navigating to /admin/foo doesn't call the /admin middleware in my case too? Both codes are similar yet they behave differently and I don't understand why x)

Good thing it's going to change in 1.0! :)

No problem!

It does/will trigger. What I was poorly illustrating is that there is likely some other global middleware that is running _before_ the /admin group gets executed. And you never _see_ it execute because that global middleware is terminating the response.

I used the example above to show that the last two .use() blocks run before /admin, even though they're defined much later in the application.

Maybe I can help you track this down if you showed me more of the code and/or told me what response you're getting for /admin/foo?

Ok I get it now! No matter the ordrer you register your middlewares, given that use(fn) register global middlewares fn will always run before any filtered middleware like use('/admin', fn).

Hence my /admin middleware not getting executed because serveStatic() probably ends the response once the target file is served. The only case where it doesn't end the response and I see the @admin log is if the URL targets a file that doesn't exist, then serveStatic() calls next() and this time the filtered middleware is run.

How would you solve this use case with the current version 0.5.2? Is it even possible?

Also, I'm curious : will polkadot also be affected by this breaking change? (I haven't tried it yet so maybe it already behaves totally differently and my question is irrelevant, but asking just in case.)

I would fix it by moving serve-static to its own path. Most of the time, you don't need it running globally (it's slow and induces a significant performance hit too).

Maybe something like this:

polka()
  .use('/assets' serveStatic)
  .use('/admin', ...)

Polkadot doesn't have a router or middleware runner built in, so you would/could arrange it however you'd like! It's not affected by anything in Polka, no :)

There is a polka@next release out btw. It has the ordering changes so it might feel more comfortable/familiar to you

Ok. Thank you!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lagmanzaza picture lagmanzaza  Â·  4Comments

motss picture motss  Â·  4Comments

deadcoder0904 picture deadcoder0904  Â·  8Comments

kevinfiol picture kevinfiol  Â·  3Comments

ansarizafar picture ansarizafar  Â·  3Comments