express: route() should handle 405 Method not allowed

I know this has been discussed in numerous issues here, but not about this specific case.

IMHO the following code

app.route('/user/:id').get(oneUser).delete(delUser).put(updateUser);

should send 405 Method Not Allowed for a POST request to /user/123.

I can of course workaround this easily by adding a .all(send405) to all of my route() calls but I couldn’t find any variable in req that would expose what methods the route does have (for Allow header).

I know there are a ton of ways how POST /user/123 could still be defined, but if you do call .route() then it would be IMO reasonable to believe that it is the only way of defining methods for that one route.

So I suggest three alternative ways how I’d like this to be fixed (in the order of preference):

  1. Make it the default behavior to send a correct 405 response if route() does not have that method.
  2. Make it configurable (per router or something) to automatically send 405 responses.
  3. Expose configured methods to be self used in all().

This most likely will raise the question about ‘How about when GET returns 404, then POST should also return 404 even though with a different id it should send 405.’

I kinda agree, and this is why I add first in chain a method:

var withUser = function(req, res, next) {
  fetchUser(req.params.id, function(err, user) {
    if (err) return next(err);
    if (!user) return res.status(404).end();
    req.user = user;
    next();
  });
};

router.route('/users/:id').all(withUser).get(sendUser).put(updateUser).delete(deleteUser).all(send405);

About this issue

  • Original URL
  • State: open
  • Created 10 years ago
  • Comments: 17 (6 by maintainers)

Most upvoted comments

In the meantime is there a way to “Hack” around this?

There may be a clever way, but the simplest way is to add a .all on your route:

router.route('/some/path')
.get(getHandler)
.post(postHandler)
.all(methodNotAllowedHandler)

function methodNotAllowedHandler(req, res) {
  res.sendStatus(405)
}