visionmedia / page.js

Micro client-side router inspired by the Express router
http://visionmedia.github.com/page.js
7.67k stars 687 forks source link

Okay to run code after a next() call in a route handler? #554

Open tiffz opened 4 years ago

tiffz commented 4 years ago

Hello!

Our team uses page.js for routing in a SPA we maintain. A debate recently came up as we tried to figure out the best way to add a handler that ran after every page load for our app.

One idea that came up was the idea of having a '*' route handler that ran before all other routes and ran some functionality after the next() call.

ie:

page('*', universalRouteHandler);

universalRouteHandler(ctx, next) {
  doStuffBeforeRouteHandlers();
  next();
  doStuffAfterRouteHandlers();
}

This solution worked well for us because it allowed us to execute some functionality before specific route handler logic and other functionality afterwards without having to create multiple '*' route handlers.

However, a teammate noticed that none of page.js's documented examples ran logic in a function after a next() call and feared that what we had come up with was a hack.

So my question is essentially: is running logic after a next() call in a handler an acceptable way to specify an order for routing behavior?

Is it a reasonable assumption that logic after a next() call would always run only when other route handlers have executed or is coding in this way depending too much on implementation details of how page.js runs route handlers? ie: if it's possible that page.js could one day change its implementation to use async code in next().

(In our app, we originally started with a '*' route handler that was registered after all other routes, but we wanted to move away from this because it made next() handling complex for our use case.)

coyotte508 commented 3 years ago

It should be fine if there's no async calls in the next handlers.

Too bad there's not a koa-like version of page, you could just do:

async function universalRouteHandler(ctx, next) {
  doStuffBeforeRouteHandlers();
  await next();
  doStuffAfterRouteHandlers();
}