[node.js] Express-js wildcard routing to cover everything under and including a path

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.

This question is related to node.js express

The answer is


For those who are learning node/express (just like me): do not use wildcard routing if possible!

I also wanted to implement the routing for GET /users/:id/whatever using wildcard routing. This is how I got here.

More info: https://blog.praveen.science/wildcard-routing-is-an-anti-pattern/


In array you also can use variables passing to req.params:

app.get(["/:foo", "/:foo/:bar"], /* function */);

It is not necessary to have two routes.

Simply add (/*)? at the end of your path string.

For example, app.get('/hello/world(/*)?' /* ... */)

Here is a fully working example, feel free to copy and paste this into a .js file to run with node, and play with it in a browser (or curl):

const app = require('express')()

// will be able to match all of the following
const test1 = 'http://localhost:3000/hello/world'
const test2 = 'http://localhost:3000/hello/world/'
const test3 = 'http://localhost:3000/hello/world/with/more/stuff'

// but fail at this one
const failTest = 'http://localhost:3000/foo/world'

app.get('/hello/world(/*)?', (req, res) => res.send(`
    This will match at example endpoints: <br><br>
    <pre><a href="${test1}">${test1}</a></pre>
    <pre><a href="${test2}">${test2}</a></pre>
    <pre><a href="${test3}">${test3}</a></pre>

    <br><br> Will NOT match at: <pre><a href="${failTest}">${failTest}</a></pre>
`))

app.listen(3000, () => console.log('Check this out in a browser at http://localhost:3000/hello/world!'))

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.


Examples related to node.js

Hide Signs that Meteor.js was Used Querying date field in MongoDB with Mongoose SyntaxError: Cannot use import statement outside a module Server Discovery And Monitoring engine is deprecated How to fix ReferenceError: primordials is not defined in node UnhandledPromiseRejectionWarning: This error originated either by throwing inside of an async function without a catch block dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.62.dylib error running php after installing node with brew on Mac internal/modules/cjs/loader.js:582 throw err DeprecationWarning: Buffer() is deprecated due to security and usability issues when I move my script to another server Please run `npm cache clean`

Examples related to express

UnhandledPromiseRejectionWarning: This error originated either by throwing inside of an async function without a catch block jwt check if token expired Avoid "current URL string parser is deprecated" warning by setting useNewUrlParser to true MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017] npm notice created a lockfile as package-lock.json. You should commit this file Make Axios send cookies in its requests automatically What does body-parser do with express? SyntaxError: Unexpected token function - Async Await Nodejs Route.get() requires callback functions but got a "object Undefined" How to redirect to another page in node.js