Express-js wildcard routing to cover everything under and including a path


Question

I'm trying to have one route cover everything under /foo including /foo itself. I've tried using /foo* which work for everything except it doesn't match /foo. Observe:

var express = require("express"),
    app = express.createServer();

app.get("/foo*", function(req, res, next){
  res.write("Foo*\n");
  next();
});

app.get("/foo", function(req, res){
  res.end("Foo\n");
});

app.get("/foo/bar", function(req, res){
  res.end("Foo Bar\n");
});

app.listen(3000);

Outputs:

$ curl localhost:3000/foo
Foo
$ curl localhost:3000/foo/bar
Foo*
Foo Bar

What are my options? The best I've come up with is to route /fo* which of course isn't very optimal as it would match way too much.

1
80
5/16/2018 5:47:04 PM

Accepted Answer

I think you will have to have 2 routes. If you look at line 331 of the connect router the * in a path is replaced with .+ so will match 1 or more characters.

https://github.com/senchalabs/connect/blob/master/lib/middleware/router.js

If you have 2 routes that perform the same action you can do the following to keep it DRY.

var express = require("express"),
    app = express.createServer();

function fooRoute(req, res, next) {
  res.end("Foo Route\n");
}

app.get("/foo*", fooRoute);
app.get("/foo", fooRoute);

app.listen(3000);
99
7/13/2018 10:00:55 AM

The connect router has now been removed (https://github.com/senchalabs/connect/issues/262), the author stating that you should use a framework on top of connect (like Express) for routing.

Express currently treats app.get("/foo*") as app.get(/\/foo(.*)/), removing the need for two separate routes. This is in contrast to the previous answer (referring to the now removed connect router) which stated that "* in a path is replaced with .+".

Update: Express now uses the "path-to-regexp" module (since Express 4.0.0) which maintains the same behavior in the version currently referenced. It's unclear to me whether the latest version of that module keeps the behavior, but for now this answer stands.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon