Reputation: 10011
I am building a RESTful API using Express. I have several modules, which get combined in a Router
, which is the loaded by the app like so:
./user/User.js:
var router = express.Router();
router.post('/login', variousMiddleware, login);
router.get('/:id', variousMiddleware, getUserDetails);
router.put('/:id', variousMiddleware, updateUser);
module.exports = router;
./app.js:
var app = express();
var routes = express.Router();
var User = require("./user/User.js");
routes.use('/user', User);
app.use('/v1/', routes);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
...
So, when I perform a POST /v1/user/login
request, or a GET /v1/nonexisting/randomness
, everything works correctly.
However, when I perform a GET /v1/user/login
or a PUT /v1/user/login
request, Express routes these as if they were GET /v1/user/:id
and PUT /v1/user/:id
respectively, instead of throwing 404 as I would expect it to.
I figure that Express interprets the login
part of the route as being a valid value for the :id
parameter in these routes.
How can I avoid this?
Upvotes: 1
Views: 55
Reputation: 10011
The required result is achievable by making the route specification unambiguous:
var router = express.Router();
router.post('/login', variousMiddleware, login);
router.get('/:id([a-f0-9]+)', variousMiddleware, getUserDetails);
router.put('/:id([a-f0-9]+)', variousMiddleware, updateUser);
module.exports = router;
By defining the range of acceptable values for ID we avoid the misinterpretation.
Upvotes: 0
Reputation: 1696
The reason GET /v1/user/login
and PUT /v1/user/login
are being handled by your '/v1/user/:id' routes is you haven't set up a PUT or GET handler for '/login'
. You've only set up the POST handler.
If you change it to:
var router = express.Router();
router.post('/login', variousMiddleware, login);
router.get('/login', variousMiddleware, login);
router.put('/login', variousMiddleware, login);
router.get('/:id', variousMiddleware, getUserDetails);
router.put('/:id', variousMiddleware, updateUser);
module.exports = router;
then you will be able to handle GET and PUT requests.
Another alternative would be to change your "/:id" route to something specifically meant to handle your RESTful operations. Something like:
var router = express.Router();
router.post('/login', variousMiddleware, login);
router.get('/data/:id', variousMiddleware, getUserDetails);
router.put('/data/:id', variousMiddleware, updateUser);
module.exports = router;
Upvotes: 0