2

I'd like to add some functionality to /module that gets executed for any matching route under that directory.

So for a given set of routes:

/module/
/module/page
/module/things
/module/things/:thingid

I want code in a router for /module to run for all of the above routes. /module doesn't render, it just fetches some common data and configures the view context. Then one of the other routes runs and renders the page.

Is this possible with koa-router? Or is there a better package?

Edit: I think maybe I have to do a nested router and add middleware prior to the nesting like so:

var subRouter = new Router();
subRouter.get('/', function *(next){ doSomething(); });
subRouter.get('/page', function *(next){ doSomething(); });
subRouter.get('/things', function *(next){ doSomething(); });
subRouter.get('/things/thingid', function *(next){ doSomething(); });

mainRouter.use('/module',
               function *(next) { doPreRouteSteps(); yield next; },
               subRouter.routes()
);

Seems to be working, but I'm not sure if this is an ugly hack or what. If there is a better way, please advise.

JC Ford
  • 6,946
  • 3
  • 25
  • 34
  • That looks like a sensible approach (i.e. not a hack). If you're interested in alternative routing middleware check out https://github.com/koajs/koa/wiki#routing-and-mounting. – Peadar Doyle Aug 11 '15 at 08:42

3 Answers3

2

You might consider using koa-mount to create a separate app, and then mount it under /module. The sub-app can have any pre- or post- middleware you'd like.

var mount = require('koa-mount');
var koa = require('koa');
var koaRouter = require('koa-router');

var subApp = koa();
var router = koaRouter();
router.get('/page', function *(next){ ... });
subApp.use(function*() { ...pre-route stuff... });
subApp.use(router.routes());

var mainApp = koa();
mainApp.use(mount('/module', subApp));

I like this approach because the way it encourages modularity.

greim
  • 9,149
  • 6
  • 34
  • 35
2

koa-router can do this, i guess better.

router.use('/module/', function *(next) {
  // code here
  next();
});

router.get('/module/page', function *() {
  this.body = 'your view';
});

on this sample, everytime the router encounters '/module'. even if there are trailing or additional params on the url. it will run the first function then proceed to any meet condition.

Rei Dien
  • 196
  • 13
1

This is Rei Dien's response updated to 2021. Also you can pass an array of routes or "/" which will call your router.use() before any route. Example with array of routes:

    router.use(["/user", "/posts"], async (ctx, next) => {
        // Your code before routes...
        await next();
    });

    router.get("/user/likes", async ctx => {
        ctx.body = "Your rute code...";
    });
fermmm
  • 1,078
  • 1
  • 9
  • 17