grape icon indicating copy to clipboard operation
grape copied to clipboard

Dynamic matching / static matching - expected behaviour

Open myxoh opened this issue 6 years ago • 9 comments

When trying to have an endpoint that matches dynamically except for specific keywords. i.e. GET resource/:id => returns the resource GET resource/new => returns a JSON schema of the resource

The issue is that when I define it this way:

class ResourceAPI
  get 'resource/:id' do
    # ...
  end

  get 'resource/new' do
    # ...
  end
end

I will never hit the resource/new endpoint. However, if I define it the other way around, it will work.

myxoh avatar Feb 01 '19 11:02 myxoh

We should document route matching and make sure we have tests for both, to start.

How do you think this should work?

dblock avatar Feb 01 '19 15:02 dblock

I've personally been avoiding declaring two routes like this and case inside of it, but I can see the appeal here of wanting to say that a more specific route always matches first, for example, and that order of declaration doesn't matter.

dblock avatar Feb 01 '19 15:02 dblock

I'd have expect it to work the way you just said: matching happening first on the most specific param, and then on the wildcard matcher, regardless of order of declaration

myxoh avatar Feb 01 '19 15:02 myxoh

I think it's not that easy, for example, /foo/:id vs. /:id/foo :)

dblock avatar Feb 02 '19 04:02 dblock

Well, I was thinking it should probably match the path from left to right. Hence if both /foo/:id and /:id/foo are defined and you call /foo/foo you will end up in /foo/:id => :id => "foo". It could also be done right to left, regardless, however (documented) way we go for, I think it's slightly better than just defaulting to which one we've defined first

myxoh avatar Feb 04 '19 10:02 myxoh

I wouldn't be so sure. Matching "whichever matches first" is also a fine strategy.

Either way what this is saying is that the matching mechanism should probably be something I can choose.

dblock avatar Feb 04 '19 18:02 dblock

I might play with the config and write some specs in which you can choose the matching behaviour then when I get to it :+1:

myxoh avatar Feb 08 '19 14:02 myxoh

This came up again in https://github.com/ruby-grape/grape/issues/2350, cc: @glebsonik.

dblock avatar Sep 17 '23 08:09 dblock

Before adding new matching strategies, let's better document the order of matching we have today. I would add recognize_path specs for all combinations (your example, nested routes, inherited APIs, mounted APIs) and add a section to README about the order of matching.

dblock avatar Sep 17 '23 08:09 dblock