Allow nested routers
ewrogers opened this issue · comments
Would be helpful to allow nested routers using router.use(...)
syntax, similar to koa-router
.
Here's an example:
const apiRouter = new Router({ prefix: '/api' })
apiRouter.use(usersRouter.routes()) // assume prefix '/users'
apiRouter.use(todosRouter.routes()) // assume prefix '/todos'
...
app.use(apiRouter.routes()) // would allow /api/users and /api/todos
I personally use awilix to dynamically load a lot of my routers/controllers and then build a parent apiRouter
like so (iterating through the IoC container via listModules()
).
This is definitely a great feature to have. PRs are welcome.
Hi, I have added route group in v0.7.0 release. It can be used like this:
const Koa = require("koa");
const Router = require("koa-tree-router");
const app = new Koa();
const router = new Router();
const group = router.newGroup("/foo");
// add a handler for /foo/bar
group.get("/bar", function(ctx) {
ctx.body = "hello, world";
});
app.use(router.routes());
app.listen(8080);
In the future, I want to make every router a route group so it is easier to use. For now, this should be enough for all kinds of nested routers.
Groups seems like a nice way of partition routes. However, I've run into a bit of trouble using it with ES6 modules. Consider the following example:
/root-apis.js
import Router from 'koa-tree-router'
export const rootApis = new Router()
rootApis.get('/ping', async (ctx, next) => {
ctx.body = `APIs — ${new Date()}`
})
/admin-apis.js
import { rootApis } from './index.js'
const adminApis = rootApis.newGroup('/admin')
adminApis.get('/ping', async (ctx, next) => {
ctx.body = `Admin APIs — ${new Date()}`
})
In order to create a new group and separate that group into a different file, I need to import the rootApis
object into the admin-apis.js
file. However, in order for the code in admin-apis.js
to run, I need to import it somewhere. If I update my root-apis.js
file like so:
/root-apis.js
import Router from 'koa-tree-router'
export const rootApis = new Router()
import 'admin-apis.js' // <-- THIS LINE ADDED
rootApis.get('/ping', async (ctx, next) => {
ctx.body = `APIs — ${new Date()}`
})
I now get an error message of
ReferenceError: Cannot access 'rootApis' before initialization
This error occurs despite adding the import 'admin-apis.js'
statement below the initialization of rootApis
because in ES6 modules, all import
statements are hoisted, and therefore occur before all other code, despite placement in the file.
As a fix for this, I'm imagining an API along the lines of this:
import Koa from 'koa'
import Router from 'koa-tree-router'
const subRouter = Router.newGroup('/foo')
subRouter.get('/bar', function(ctx) {
ctx.body = 'hello, world'
})
const rootRouter = new Router()
rootRouter.addGroup(subRouter)
const app = new Koa()
app.use(router.routes())
app.listen(8080)