Sree Sajai
Sree Sajai

Reputation: 75

Express route declaration

I have 2 routes such as,

router.get("/project/:id", (req,res) => {

console.log(1);

});

router.get("/project/active", (req,res) => {

console.log(2);

})

Whenever I call the /project/active route, /project/:id route is getting called.

Any tips here would help.

Upvotes: 3

Views: 259

Answers (2)

jfriend00
jfriend00

Reputation: 708136

Your wildcard route with :id in it is greedy and is matching everything including the /project/active URL.

In this route definition:

router.get("/project/:id", ...)

The :id part is a wildcard. It matches ANYTHING. So, /project/anything will match that, including /project/active. Since routes are matched in Express in the order they are declared, your router.get("/project/:id", ...) route matches first and takes the request.

There are four ways around this:

  1. Don't design or declare conflicting routes that might both match a particular URL. In this particular case, you would change one of your two URLs to something unique such as /project/id/:id and /project/active or /project/:id and /activeproject. Then, these two route handlers will never conflict.

  2. Very carefully order your routes from the most specific to the least specific. In this case, you would put router.get("/project/active", ...) before router.get("/project/:id", ...). That gives the more specific route a chance to match before the wildcard route gets to take the request. But, note that this means that your id value can never be named active.

  3. If your ids are uniquely identifiable and different from strings like active (like suppose an ID is all numbers or always contains some numbers), then you can code a regex for the ID that would only match your id values and would not match regular words like `active.

  4. Code your wildcard route to individually check for things it should not match and call next() to continue routing to other routes.

Upvotes: 2

Nicholas
Nicholas

Reputation: 2863

That happens because you specify a dynamic route before a specific route.

The right one should be:

router.get("/project/active", (req,res) => {
  console.log(2);
});

router.get("/project/:id", (req,res) => {
  console.log(1);
});

In Node.js, we know something that is called a middleware stack. Basically, your requests will pass through middlewares until something gives out a response. Routers are also examples of middlewares.

In this case, your route assumes that /active is an id, as you defined /:id first before /active. Different things (should be your expected behavior) would happen if you switched the order.

References:

Upvotes: 0

Related Questions