Andrey Kon
Andrey Kon

Reputation: 797

How can I obtain matched route pattern in express JS?

I want my logger middleware to log each matched route when response is sent. But there may be any number of nested subroutes. Let's suppose I have this:

var app = express();
var router = express.Router();

app.use(function myLogger(req, res, next)
{
    res.send = function()
    {
        //Here I want to get matched route like this: '/router/smth/:id'
        //How can I do this?
    });
}

app.use('/router', router);

router.get('/smth/:id', function(req, res, next)
{
  res.send(response);
});

Is it possible?

Upvotes: 16

Views: 12669

Answers (2)

srquinn
srquinn

Reputation: 10501

Because app-level middleware has no knowledge of routes, this is impossible. However, if you use your logger middleware as route middleware like:

router.get('/smith/:id', logger, function (req, res) { ... });

You can use a combination of two parameters on the request object:

req.route.path => '/smth/:id'
req.originalUrl => '/router/smth/123'

I'll leave it up to you how you want to combine both into one string.

Upvotes: 19

Adze
Adze

Reputation: 164

Here's the code (in express 2.x)

// npm -v express       
// 2.14.2
var app = express();
var router = express.Router();

app.use(function(req, res, next) {
  var routes = app.routes; // See Reference 1.

  for(var method in routes) {
    if(routes.hasOwnProperty(method)) {
      for(var route in routes[method]) {
        if(req.url.toString().match(routes[method][route].regexp)) {
          console.log('Route Debugger: ' + routes[method][route].path);
        }
      }
    }
  }
  next();
});

app.use('/router', router);

router.get('/smth/:id', function(req, res, next)
{
  res.send(response);
});

What does this do?

  1. It queries the app.routes object. Now we have access to all the routes defined in our application.
  2. We match the current url req.url with the regular expression of each route.
  3. Since this is a application level middleware, it runs for every request. So you get logging like Route Debugger: /router/smth/:id, if you hit a url like /router/smith/123

Reference 1 : http://thejackalofjavascript.com/list-all-rest-endpoints/
Reference 2 : How to get all registered routes in Express?

Upvotes: 4

Related Questions