At my website.com/v2/bridge/:locationId/process endpoint, the incoming req.body looks like this:
{
choice: 'a',
data: [
{
...
},
...
]
}
I want to access a particular route depending on what the value of req.body.choice is. If req.body.choice === 'a' then I want to go on to website.com/v2/bridge/:locationId/process/choiceA with the same req being passed on.
I don't know what middleware I need to use to accomplish that. I don't know if that is even possible.
My extremely simplified routes:
// website.com/v2/bridge
const proc = require('./process');
router.use('/:locationId/process', proc);
module.exports = router;
// website.com/v2/bridge/56/process
router.use(function (req, res, next) {
// ?????????????????????????
next();
});
const choiceA = require('./choice-a');
const choiceB = require('./choice-b');
router.use('/choice-a', choiceA);
router.use('/choice-b', choiceB);
module.exports = router;
// website.com/v2/bridge/56/process/choice-a
router.post('/', function (req, res) {
res.send('I got here.');
return;
});
module.exports = router;
What middleware function do I need to include to conditionally route my request? I am trying to avoid one giant function with if statements that process different things according to the value of req.body.choice.
This will be little trickier for you...give it a try
router.use(function (req, res, next) {
req.path = "/" + "choice-"+req.body.choice
req.url = "/" + "choice-"+req.body.choice
next();
});
now it'will do the request to the end point you want
As part of finding the answer for the same question, I came across with this question, which didn't settle my mind by messing with the req.url, so here's how I got it done (I know it's a long delay, but better late than never):
When you're dealing with routers, and you want to make a condition to decide whether to use, you can do it with two ways (according to expressjs doc), and let's learn them by examples
function skipThisRouteMiddleware (req, res, next) {
if (true === isAmazingValidation) {
return next('route');
}
return next();
}
router.get('/user/:id',
skipThisRouteMiddleware,
getUserV1 // TBD - your old route
)
router.get('/user/:id',
getUserV2 // TBD - your new route
)
In the case above, when you have two routes, and you want to conditionally pick one of them, it can be done by specifying a middleware that makes the validation for the first route only, and when needed, it triggers next('route') which skip to the next matching route, please note that you must specify METHOD and not generally app.use()
// routers/index.js
const mainRouter = express.Router();
mainRouter.use(oldRouter);
mainRouter.use(newRouter);
// routers/old.js
const oldRouter = express.Router();
function canUpgradeToNewRouter (req, res, next) {
if (true === isAmazingValidation) {
return next('router'); // now it's 'router' and not 'route'
}
return next();
}
oldRouter.use(canUpgradeToNewRouter);
// routers/new.js
const newRouter = express.Router();
newRouter.use(...);
In this case, you have two different routers, and you want to conditionally pick one of them. for this case, you'll have to create a parent router (mainRouter) and two nested routers (oldRouter, newRouter).
The trick here is that the oldRouter tries to run a middleware validation that tries to "upgrade" the requester to the new shiny router, if the condition is true, it will skip the whole oldRouter, and pass the stick to the parent router mainRouter to continue matching routes to this request (the magic - next('router')), which eventually pick the upcoming newRouter
In both methods, we let the first route to make the logic and choose between itself and the others, that's a different perception (a bit)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With