Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Express know which Router path to use when multiple paths match?

Say there are 2 router.route(), for example:

router.route('/app/:id').get(funtion(req, res, next){
    console.log("id route")
});

and

router.route('/app/:username').get(funtion(req, res, next){
    console.log("user route")
});

When GET /app/nsuzuki is called, which router.route() does it use and why?

like image 577
NathanSuzuki Avatar asked Jul 26 '15 01:07

NathanSuzuki


People also ask

How does Express handle multiple routes?

The express. Router() function is used to create a new router object. This function is used when you want to create a new router object in your program to handle requests. Multiple requests can be easily differentiated with the help of the Router() function in Express.

What is route path in Express?

A route is a section of Express code that associates an HTTP verb ( GET , POST , PUT , DELETE , etc.), a URL path/pattern, and a function that is called to handle that pattern.

Can we use multiple routes in one application?

js Express App. When designing the routing system of the server, you have to make sure you have only one routing handler per path. Duplicating handler will affect the global performance of the server creating latency issues.

How is it possible to create Chainable route handlers for a route path in Express JS?

By using app. route() method, we can create chainable route handlers for a route path in Express.


1 Answers

To fully understand this, please read the documentation: http://expressjs.com/api.html#router.METHOD

How Express Routes Capture Paths

When you use a :param as a part of your path, it matches everything like /*, and the captured value is stored in req.params.param.

When you have more than one rule, the first one registered is the first one checked against. It checks each call against each rule until a match is found. If you call next() with no values passed to it, it will look for the next match (either in the same route, or continue on into the next middleware).

So these three rules will all be run

var handleRoute = function(req, res, next){
   console.log(req.path + ' ' + req.params.id + ' ' + req.params.user + ' ' + req.params[0]);
   next();
}

route.route('/user/:id').get(handleRoute);
route.route('/user/:user').get(handleRoute);
route.route('/user/*').get(handleRoute);

When I request /user/foobar, I'll see the following output (and probably an error as a client because I never responded :P)

/user/foobar foobar undefined undefined
/user/foobar undefined foobar undefined
/user/foobar undefined undefined foobar

It will hit all three, but the context is different for each.

How to Capture Path Patterns with Regular Expressions

If you want to capture separate routes for id (let's say all numbers) and user name (all letters), you can do this:

var handleRoute = function(tag) {
  return function(req, res, next) {
    console.log(tag + ' ' + req.path + ' -> ' + req.params[0]);
    res.status(200)
      .json({
        success: 'yay!'
      });
  };
};

route.route(/^\/user\/([0-9]+)$/i)
  .get(handleRoute('id'));
route.route(/^\user\/([A-Za-z]+)$/i)
  .get(handleRoute('user'));
route.route('/user/*')
  .get(handleRoute('catch all'));

Note the parathesis around my capture group. Without this, params is empty. It auto captures with just * in the string because they are nice folks. I'll get the following for output when I run against the three different types.

id /user/123 -> 123
user /user/user -> user
catch all /user/user.1 -> user.1

All that explained, you're opening yourself up to some vectors for bugs to infest your system. Might want to think about your URL pattern.

like image 76
Chris Anderson-AWS Avatar answered Oct 06 '22 16:10

Chris Anderson-AWS