Reputation: 1493
I think I'm missing somthing simple...
Simply put, why does this work:
router.use('/:object', require('../v1/routes'));
But this not? [EDITED after Evert's answer, below]
function getRouter(req, res, next) {
return require('../v1/routes');
}
router.use('/:object', getRouter());
where '../v1/routes' contains simply:
const express = require('express');
const router = express.router({ mergeParams: true });
router.get('/', getAll);
function getAll(req, res, next) {
res.send("Hello");
}
module.exports = router;
I was hoping to dynamically require the files using the API version as a filesystem base. Further up the chain I get the API version as part of the URL, so I was hoping to use that to drive the directory for the included routing file:
function getRouter(req, res, next) {
return require(`../${req.params.apiVersion}/routes`);
}
Is there any way to include the router by require-ing its filepath dynamically?
Thanks for any help.
EDIT 1 If I return my function call as I originally had it:
function getRouter(req, res, next) {
console.log(req.params.apiVersion);
return require(`../${req.params.apiVersion}/routes`);
}
router.use('/:object', getRouter);
I actually get 'v1' written in the console log; so the parameters are there in fact, but the 'return require'... doesn't seem to be working as I imagined.
EDIT 2 - SOLUTION Thanks to Evert's hints, I eventually got there:
function getRouter(req, res, next) {
const dynamicRouter = require(`../${req.params.apiVersion}/routes`);
return dynamicRouter(req, res, next);
}
router.use('/:object', getRouter);
Upvotes: 0
Views: 52
Reputation: 99523
I'll answer just the first portion of this question.
These two are not equivalent:
// #1
router.use('/:object', require('../v1/routes'));
// #2
function getRouter() {
return require('../v1/routes');
}
router.use('/:object', getRouter);
In the first snippet you are returning the result of require
to router.use
. In the second you are returning a function that returns the result of getRouter()
to router.use.
To make these equivalent, the second one has to look like this:
router.use('/:object', getRouter());
Now we're calling getRouter
instead of just passing it.
Overall I think this pattern is really strange though. Especially since you are creating another router in v1/routes
. I don't think the top-level router does anything here. Just define this is a general middleware instead.
But, this should at least explain the difference between the first 2 calls.
Upvotes: 1