1

So I have the following route:

app.delete('/project/:id', crud.deleteProject);
app.delete('/project/resource/', crud.removeResourceFromProject);

When I run the ajax call with the url http://mysite.no/project/resource/:

delete: function(url,data) {
return $.ajax({
  url: url,
  type: "DELETE",
  dataType: 'json',
  data: data
});

Express runs the crud.deleteProject function.

If I comment out or move it below the other route, it works as expected.

Why is this?

Steven
  • 19,224
  • 47
  • 152
  • 257
  • 5
    In this case, the order of routes is very important. `:id` could be anything (eg. `135`, `foo`, `resource`). So, if your routes are declared the way you did, Express will find a match for `'/project/:id'` and will stop there. If you try to match `'/project/resource/'` first, it will not go on to check for other routes. – blex Sep 17 '17 at 12:25
  • What's the point of using `:whatever` if express doesn't match it exactly? I thought the whole point of routing was to match specific url's. – Steven Sep 17 '17 at 12:53
  • 1
    `:whatever` will, indeed, match anything. It can be useful in many situations, for example, to get a search query, which could contain numbers, letters, etc. However, you can restrict it to only numbers if you want to. Take a look at this question: https://stackoverflow.com/questions/11258442/express-routes-parameter-conditions – blex Sep 17 '17 at 12:59
  • Sorry if I'm a bit slow here, but... `:id` is a parameter, whilst `/resource/` is a path. So Express doesn't distinguish these two? – Steven Sep 17 '17 at 13:01
  • 1
    It does not know whether `resource` is a path or a parameter, until it finds a route that matches. If the first route that matches says it's a parameter, then it'll treat is as one. If the first route that matches says it's a path, then it'll treat it as a path. As I said earlier, the order of your middlewares is very important. You should check for the most specific routes first, and then the most "permissive" ones – blex Sep 17 '17 at 13:04
  • Right, thanks. One last Q. Is this Express specific? Or does this logic apply to routing methods in general? – Steven Sep 17 '17 at 13:50
  • 1
    I've not worked with many route handlers, so I can't say it _always_ applies, but this logic also applies when using PHP CodeIgniter. And also when using URL rewriting in a .htaccess or vhosts file. You declare specific routes first so they match first, and then, the ones that may contain different parameters. – blex Sep 17 '17 at 15:47

1 Answers1

0

In Express, the order of your routing definitions is important. It will perform the first matching route. As Blex states, '/:id' is a wildcard value and is matching '/resource' instead of skipping past and following the correct route definition.

A solution is to switch the definitions to have '/project/resource' defined before '/project/:id'

A solution is to add another path layer eg '/project/res/resource' instead of '/project/resource' as Express will not match this to '/:id'.

Imogen T
  • 46
  • 2
  • 1
    The easiest solution is to move the definition of static routes to above and all the `wildcards` should be below them. – Raghav Garg Sep 17 '17 at 13:15