Skip to content

Instantly share code, notes, and snippets.

@mwarner1
Last active July 16, 2018 20:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mwarner1/45ccd9a0ccba0fe55936d94f9c56b9be to your computer and use it in GitHub Desktop.
Save mwarner1/45ccd9a0ccba0fe55936d94f9c56b9be to your computer and use it in GitHub Desktop.
koa-router with embedded wildcards
/**
* Adaptation of the koa-mount boilerplate example expanded to include wildcards.
* Unfortunately, there are a number of bugs with wildcard matching and koa-router.
* Below is a workaround which consists of using regular expressions to "match all except"
* instead of a plain wildcard.
*
* Use at your own risk.
* --Matt Warner, July 2018
*
* Original note:
* This example illustrates how you may
* implement a cascading effect using
* several mounted applications that
* are not aware of where they are mounted:
*
* GET /foo
* GET /foo/bar
* GET /foo/bar/baz
*/
'use strict';
const mount = require('koa-mount')
const Koa = require('koa')
const Router = require('koa-router');
const app = new Koa();
const a = new Koa();
const b = new Koa();
const c = new Koa();
const d = new Koa();
const routerA = new Router();
const routerB = new Router();
const routerC = new Router();
const routerD = new Router();
a.use(routerA.routes(), routerA.allowedMethods());
b.use(routerB.routes(), routerB.allowedMethods());
c.use(routerC.routes(), routerC.allowedMethods());
d.use(routerD.routes(), routerD.allowedMethods());
routerA.get(/^(?!\/bar).*$/, async ctx => { // everything that isn't /foo/bar gets caught here
ctx.body = 'Hello world from A';
});
routerB.get(/^(?!\/(baz|boo)).*$/, async ctx => { // everything that isn't /foo/bar/baz or /foo/bar/boo gets caught here
ctx.body = 'Hello world from B';
});
routerC.get(/^.*$/, async ctx => { // match everything starting with /foo/bar/baz
ctx.body = 'Hello world from C';
});
routerD.get(/^.*$/, async ctx => { // match everything starting with /foo/bar/boo
ctx.body = 'Hello world from D';
});
app.use(mount('/', a)) // /
a.use(mount('/bar', b)); // /bar
a.use(mount('/bar/baz', c)) // /bar/baz
a.use(mount('/bar/boo', d)) // /bar/boo
// Debug print of the routes each router has configured
console.log("A", routerA.stack.map(i => i.path));
console.log("B", routerB.stack.map(i => i.path));
console.log("C", routerC.stack.map(i => i.path));
console.log("D", routerD.stack.map(i => i.path));
app.listen(3001)
console.log('listening on port 3001')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment