-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Grape recognize_path incorrectly recognizes path #2350
Comments
Do you think you can you turn this into a failing test? |
If there is a way to predefine two routes or somehow simulate this then yes. Where should I set up this test? UPD: I've taken a look at the Anyway, I'll just place it here for now until I understand what is the better way to share it # frozen_string_literal: true
require 'rails_helper'
describe Grape::API do
describe '.recognize_path' do
subject { Class.new(described_class) }
context 'given parametrized route and static route' do
it 'recognizes it as static' do
subject.get('/foo/:id') {}
subject.post('/foo/share') {}
actual = subject.recognize_path('/foo/share').routes[0].origin
expect(actual).to eq('/foo/share')
end
end
end
end |
You can make a pull request on top of the existing specs, so
Looking at the problem though, I wonder if this is a bug at all. AFAIK routes in Grape are matched in order of declaration, not like Ruby methods where the last one wins - it's the first one that matches. Amazingly, I actually couldn't find anything on this in our README, and I think we need to state it unambiguously in it. In fact, there's #1858 that asks for the same. Want to take it on? I would add |
@glebsonik Btw, in your specific example you have a |
@dblock I've done a commit but I can neither create a PR to the grape repo nor push my changes. I think, I just don't have access to do this. Is there any other way I should address my PR? I cloned the repo and checked out a new branch from the master |
Okay nvm, I've just created PR in the fork #2352 |
Hi 👋 I was taking a look at this issue, and as the first step I can add a section in the README talking about the order of matching, as you suggested in your comment above @dblock. Agree? On the other hand, I find this issue pretty interesting, as it's not the first time I need to change the order of my endpoints to make them work. So I was trying to debug the issue following the tests added by @glebsonik in #2352. Seems that the problem is that the regular expression that Mustermann generates is not taking into account the type of the parameter. This is the current regular expression generated by /(?-mix:\A(?-mix:\/(?:b|%62)(?:o|%6f|%6F)(?:o|%6f|%6F)(?:k|%6b|%6B)(?:s|%73)\/(?<id>(?:(?!(?:\.|%2e|%2E)(?:(?!(?:\.|%2e|%2E))[^\/\?#.])+?$)[^\/\?#.])+)(?:(?:\.|%2e|%2E)(?<format>[^\/\?#.]+))?)\Z)/ This regular expression should only match if the content of the 3.2.2 :002 > "/books/1".match?(regex)
=> true
3.2.2 :003 > "/books/share".match?(regex)
=> true
3.2.2 :004 > If I manually change the regular expression generated for the /(?-mix:\A(?-mix:\/(?:b|%62)(?:o|%6f|%6F)(?:o|%6f|%6F)(?:k|%6b|%6B)(?:s|%73)\/(?<id>\d?+)(?:(?:\.|%2e|%2E)(?<format>[^\/\?#.]+))?)\Z)/ You can see that the 3.2.2 :002 > "/books/1".match?(regex)
=> true
3.2.2 :003 > "/books/share".match?(regex)
=> false
3.2.2 :004 > So I was trying to see the options that we are sending to instantiate the Mustermann::Grape.new("/books/:id(.:format)", {:uri_decode=>true}) However, the options received when initialising the pattern class contains much more interesting information that can be really useful for generating a much more precise regular expression.
I can see that Grape is using its own Mustermann pattern , so don't know if adding extra information to the pattern options we can generate much more precise regular expression, or if we need to update the What do you think @dblock ? Any suggestion for start digging on it? Thanks! |
Yes.
This is a bit over my head, by now you understand way more than me of what's happening here ;) @namusyaka though might have an opinion. I do see that musterman-grape hasn't been updated for a while, generally a good place to contribute! |
Hey @dblock @namusyaka , I've added a PR with the proper changes in the Can you take a look? ruby-grape/mustermann-grape#21 After that, and if you consider this change is appropiated, I would continue passing the params when initialising the EDIT: I've just ran the tests provided by @glebsonik using my local gem Comments, suggestions and feedback are totally welcome. |
…aking into account the route_param type
…aking into account the route_param type
…aking into account the route_param type
Solved in #2379 |
Problem
I faced an issue with path recognizing using recognize_path from Grape::API ancestor, here is an example of the API structure I have
If I try to use
Books.recognize_path('/books/share')
Then it will recognize it asGET /books/:id
request instead of thePOST /books/share
I guess this happens because the
recognize_path
does not rely on the request method. In this case Grape recognizer treats share as :id param instead of pathThe text was updated successfully, but these errors were encountered: