71

I have a route on my Express app that looks like this:

app.get('/:id', function (request, response) {
  …
});

The ID will always be a number. However, at the moment this route is matching other things, such as /login.

I think I want two things from this:

  1. to only use this route if the ID is a number, and
  2. only if there isn't a route for that specific paramater already defined (such as the clash with /login).

Can this be done?

nbro
  • 15,395
  • 32
  • 113
  • 196

3 Answers3

142

Expanding on Marius's answer, you can provide the regex AND the parameter name:

app.get('/:id(\\d+)/', function (req, res){
  // req.params.id is now defined here for you
});
Fluffy
  • 27,504
  • 41
  • 151
  • 234
danmactough
  • 5,444
  • 2
  • 21
  • 22
  • Great, but now if I have a route for say `/1` elsewhere, it's still going to call that. Anyway to prevent this? –  Jun 29 '12 at 10:56
  • 14
    As long as the explicit `/1` route is added first it will take precedence. – JohnnyHK Jun 29 '12 at 11:18
  • 2
    You can place the explicit routes first, as JohnnyHK says. You may also be able to define the RegEx to not match the routes you want to skip. – danmactough Jun 29 '12 at 14:51
  • Order your route handlers in priority order and then use `function(req, res, next)`, calling next() from within any route when your logic knows that it needs to pass control onto the next route handler in line. – awhie29urh2 Apr 18 '13 at 00:07
  • if you use an alpha-numeric id like Mongo ObjectID you will need to change the regex – Alexander Mills Nov 01 '15 at 23:47
  • Great! Works for me. Express version `~4.15.3`. I could make two routes with this technique: `/users/online` and `/users/21`, `/users/online` and `/users/:id(\\d+)` respectively. – Green Sep 04 '17 at 05:58
  • is the id parameter optional in this route? If not, how would I make it optional? I know that '/:id?' makes the id parameter optional but do I still need the question mark and, if so, where would it go? – T. Stoddard Nov 07 '19 at 18:41
12

Yes, check out http://expressjs.com/guide/routing.html and https://www.npmjs.com/package/path-to-regexp (which express uses). An untested version that may work is:

app.get(/^(\d+)$/, function (request, response) {
  var id = request.params[0];
  ...
});
Marius Kjeldahl
  • 6,830
  • 3
  • 33
  • 37
4

You can use:

// /12345
app.get(/\/([^\/]+)\/?/, function(req, res){
  var id = req.params[0];
  // do something
});

or this:

// /post/12345
app.get(/\/post\/([^\/]+)\/?/, function(req, res){
  var id = req.params[0];
  // do something
});
Marco Godínez
  • 3,440
  • 2
  • 21
  • 30