Reputation: 33
Is it possible to make router in ExpressJS like this?
users.js
const userController = ('../controllers/userController.js');
router.get('/:userName', userController.paramByUsername);
router.get('/:id', userController.paramByUserId);
In the controller, the code look like this
userController.js
function paramByUsername(req, res) {
User.findOne({
where: {
userId: req.params.userId
}
})
.then((user) => {
if(!user) {
return res.status(404).json({ message: "User not found."});
}
return res.status(200).json(user);
})
.catch((error) => {
return res.status(400).json(error);
});
}
function paramByUserId(req, res) {
User.findByPk(req.params.id)
.then((user) => {
if(!user) {
return res.status(404).json({ message: "User not found."});
}
}).catch((error) => {
return res.status(400).json(error);
});
}
By the code above, what I wanted to achieve is the endpoint like this:
/users/1
this should response same as /users/username
.
I have tried the code above, but what I see is an error when I get /users/:id
Upvotes: 0
Views: 70
Reputation: 708036
You can't do both of these together:
router.get('/:userName', userController.paramByUsername);
router.get('/:id', userController.paramByUserId);
From a pure routing point of view, there is no way to tell the difference between these two. Whichever route you declare first will grab everything at the top level and the second will never get hit.
So, in route design, you HAVE to make sure that each route is uniquely recognizable to the Express route matcher based on what you put in the route pattern.
I suppose that if an id
was always just numbers and a username could never be just numbers, then you could use a regex route and match only numbers for the id and everything else for the username, but that seems a bit fragile to me and I'd prefer something a bit more explicit.
I don't know the overall landscape of your app, but you may want to do:
router.get('/user/:userName', userController.paramByUsername);
router.get('/id/:id', userController.paramByUserId);
Or, you could use the query string with URLs like this:
/search?user=John
/search?id=4889
And, then you'd just have one route:
router.get("/search", ....);
And you would examine which properties are present in req.query
to decide which item you were looking for.
Upvotes: 1