I have my routes setup as below.
const express = require('express');
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// load routes
require('./loader/routes')(app);
module.exports = app;
const Router = require('../router');
// Middlewares
const auth = require('../middlewares/auth');
module.exports = function getRoutes(app) {
app.use('/api/v1/services', Router.ServiceRoutes);
app.use('/api/v1/master-vehicles', Router.MasterVehicleRoutes);
}
md5-4e0bd7a17ad3d9fbc4a1e2be43c53fde
const router= require('express').Router();
const MasterVehicleController = require('../controllers/MasterVehicleController');
const MasterVehicleRoutes = require('./MasterVehicleRouter')({
router: express.Router(),
MasterVehicleController,
makeExpressCallback,
});
const ServiceController = require('../controllers/ServiceController');
const ServiceRoutes = require('./ServiceRouter')({
router: express.Router(),
ServiceController,
makeExpressCallback,
});
md5-4e0bd7a17ad3d9fbc4a1e2be43c53fde
module.exports = ({
router,
MasterVehicleController,
makeExpressCallback,
}) => {
router.get(
'/',
makeExpressCallback(MasterVehicleController.getAllVehicles),
);
router.get(
'/:id',
makeExpressCallback(MasterVehicleController.getVehicleById),
);
return router;
};
md5-4e0bd7a17ad3d9fbc4a1e2be43c53fde
module.exports = ({
router,
ServiceRequestController,
makeExpressCallback,
}) => {
router.put(
'/',
makeExpressCallback(ServiceRequestController.changeRequestStatus),
);
router.get(
'/:id',
makeExpressCallback(ServiceRequestController.getRequestDetail),
);
return router;
};
It is matching routes randomly, sometimes it matches with master-vehicles and sometimes it matches with some other routes.
Why is this happening?
I could solve it though by passing new instances of router to each one like router: express.Router()
Hi @sujeet-agrahari I'm sorry you're having the issue. It should not be matching at random. Unfortunately there is not enough information here for us to reproduce the issue and help take a look into what is happening. Can you provide enough code where we can start a running app and ten provide the exact HTTP method/URL you are calling the server with to experience the issue? Thank you very much.
@dougwilson I have updated the comment and have added other codes.
I tried to reproduce it in krzysdz/express_4510, but it seems like the routes match correctly:
/api/v1/master-vehicles - getAllVehicles from controllersMasterVehicleController.js/api/v1/master-vehicles/anything - getVehicleById from controllersMasterVehicleController.js/api/v1/services - changeRequestStatus from controllersServiceController.js/api/v1/services/anything - getRequestDetail from controllersServiceController.js@sujeet-agrahari can you provide more information (especially what request causes unexpected behaviour)? Can you reproduce your problem with the code from my repository?
If I pass same router instance in all routes, it matches randomly. As I have mentioned above, when I passed a new instance of router to each router it works fine.
So, my question is what was causing the issue?
On your query, GET /services hits GET /master-vehicles api.
To be sure I also crossed check controller mapping to routes, they were fine.
That's because the same router answers requests to /api/v1/services and /api/v1/master-vehicles and you define the handler for GET /:id twice for this router (here and here).
I don't know why this is random, but the problem is that you tried to define two handlers for GET /....
Are you sure that you want /services and /master-vehicles work exactly the same? That's why you would use the same router for multiple paths.

No not at all, I want the specific request to go to their respective handler, they shouldn't collide.
As I have mentioned before, I have solved the issue already. It is working as below, that is expected.
GET /api/v1/services -> ServiceRequestController.getAllServices
GET /api/v1/services/:id -> ServiceRequestController.getServiceById
&
GET /api/v1/mster-vehicles-> MasterVehicleController.getAllMasterVehicles
GET /api/v1/master-vehicles/:id -> MasterVehicleController.getMasterVehicleById
As I have mentioned before, collision only happens when same router instance is shared in each routes.
_When I pass a new router instance to each route it works as expect, as I have stated in this reply above._
My concern is,
_Even if router instance is same, their path prefix is different, /services & /master-vehicles . Rather than following the match why it is hitting randomly?_
I really appreciate your effort taking time and replyin back.
Router does not consider its path prefix when routing the request. The prefix is "removed" (not really, it's still possible to check it) before the request is routed by the router. The paths in the router are relative to the router base.
This means that if you have one router instance with handler for GET / and mount it under /a and /b, both of these paths will use that handler.
Check this example to see what I mean:
const express = require("express");
const router = express.Router();
router.get("/", (req, res) => {
res.type("text/html")
.send(`path: ${req.path}<br>
originalUrl: ${req.originalUrl}<br>
url: ${req.url}<br>
baseUrl: ${req.baseUrl}`);
});
const app = express();
app.use("/a", router)
.use("/b", router);
const server = app.listen(() => {
console.log(`/a: http://127.0.0.1:${server.address().port}/a
/b: http://127.0.0.1:${server.address().port}/b`)
});
For /a:
path: /
originalUrl: /a
url: /
baseUrl: /a
and for /b:
path: /
originalUrl: /b
url: /
baseUrl: /b