koajs / joi-router

Configurable, input and output validated routing for koa

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Nested router prefix

thakkaryash94 opened this issue · comments

How I can have sub router with prefix and add main router with another prefix?

userRoutes.js

import router from 'koa-joi-router';
const userRouter = router();
userRouter.prefix('/user');
const userRoutes = [...];
userRouter.route(userRoutes);
export default userRouter;

mainRoutes.js

import router from 'koa-joi-router';
import userRouter from 'userRoutes';
apiRouter.prefix('/app');
apiRouter.route(userRouter.routes);
export default apiRouter;

server.js

import AppApiRouter from 'mainRoutes';
app.use(AppApiRouter.middleware());

So actually, now my userRouter uri should be '/app/user/path'. Instead it is replacing prefix with new prefix string. In mainRoutes.js , apiRouter.route is directly accessing userRoutes.routes object. We are adding prefix as key in router object, that's why mainRouter is not able to get new path.

How to solve this?

I believe the root cause of your issue is that .prefix() doesn't prepend '/users' to each route, so that when you got to your apiRouter and run apiRouter.route(userRouter.routes); apiRouter doesn't get any information on what userRouter's prefix is. you'd have to request an enhancement (or make a pull request) to perhaps add a method like .compose() where it takes in another router, and adds it together, prefix, routes, and options.

I think if you want a short-term fix, you'd have to mount the userRouter separately, I think in server.js you need a similar entry in your server.js

app.use(userRouter.middleware());
app.use(apiRouter.middleware());

for each router that you want to have a unique prefix on. unless there's a way to have the api be composeable (perhaps other contributors can chime in, I'm just a novice user).

The way i've been able to compose paths is by having the parent route use the child routes as middleware, effectively composing them. YMMV

import router from 'koa-joi-router';
const userRouter = router();
userRouter.prefix('/user');
const userRoutes = [...];
userRouter.route(userRoutes);
export default userRouter;
import router from 'koa-joi-router';
import userRouter from 'userRoutes';
apiRouter.prefix('/app');
apiRouter.use('', userRouter);
export default apiRouter;

@pixeldrew that's interesting approach and it is working. Thanks a lot.

My ideal solution is to recursively add files in a directory as a route using the package 'require-directory'. These can either be descriptor literals that are the params to the Router.route method or Router objects themselves, as a rough example:

const Router = require('koa-joi-router');
const routes = require('require-directory')(module, {
  visit: (module) => {
    if (module instanceof Router) {
      return module;
    }
    const router = Router();
    router.route(module);
    return router;
  },
});

const router = Router();
// root url
router.prefix('/app');

const addChildRoute = (path, [key, route]) => {
  if (route instanceof Router) {
    router.use(path, route);
  } else {
    Object.entries(route).forEach(addChildRoute.bind(null, `${path}/${key}`));
  }
};

Object.entries(routes).forEach(addChildRoute.bind(null, ''));

It'd be good to have @aheckmann chime in on whether or not this approach seems valid. When debugging routes i've noticed that koa-router is checking a lot of invalid routes.

Closing due to inactivity. Please reopen with a reproducible example if the issue persists.