From dfc46a7f6f91bd1dcb0d01f98150e5d3e18deffe Mon Sep 17 00:00:00 2001 From: Andreas Haller Date: Fri, 15 Aug 2025 17:13:48 +0200 Subject: [PATCH 1/4] Add failing test about routing paths with dynamic segments without slashes --- spec/router_spec.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/spec/router_spec.rb b/spec/router_spec.rb index 4ebd5c4f..ee84c5fb 100644 --- a/spec/router_spec.rb +++ b/spec/router_spec.rb @@ -8,7 +8,8 @@ [ double(path: '/{id}', request_method: 'get'), double(path: '/{id}', request_method: 'patch'), - double(path: '/a', request_method: 'get') + double(path: '/a', request_method: 'get'), + double(path: '/a{format}', request_method: 'get') ] end @@ -30,6 +31,13 @@ expect(router.match('GET', '/c/d').error).to have_attributes(type: :not_found) end + it 'can match a path fragment with a variable' do + match = router.match('PATCH', '/a.json') + expect(match.request_definition.path).to eq('/a{format}') + expect(match.request_definition).to be(requests[1]) + expect(match.params).to eq('format' => '.json') + end + it 'returns an incomplete match for unknown request method' do expect(router.match('DELETE', '/b').error).to have_attributes(type: :method_not_allowed) end From cf5b50564b4cc50bb685ce0b0b5ffacb386f7f7d Mon Sep 17 00:00:00 2001 From: Jan Douwe Beekman Date: Tue, 19 Aug 2025 11:34:20 +0200 Subject: [PATCH 2/4] The required changes --- lib/openapi_first/router.rb | 9 +++++++-- spec/router_spec.rb | 9 ++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/lib/openapi_first/router.rb b/lib/openapi_first/router.rb index 9f04ec8a..d94e9ff7 100644 --- a/lib/openapi_first/router.rb +++ b/lib/openapi_first/router.rb @@ -97,10 +97,15 @@ def find_path_item(request_path) found = @static[request_path] return [found, {}] if found - @dynamic.find do |_path, path_item| + matches = @dynamic.filter_map do |_path, path_item| params = path_item[:template].match(request_path) - return [path_item, params] if params + next unless params + + [path_item, params, params.values.sum(&:length)] end + + matches&.min_by { |_path_item, _params, length| length } + &.then { |path_item, params, _length| [path_item, params] } end end end diff --git a/spec/router_spec.rb b/spec/router_spec.rb index 4ebd5c4f..a2cda131 100644 --- a/spec/router_spec.rb +++ b/spec/router_spec.rb @@ -8,7 +8,8 @@ [ double(path: '/{id}', request_method: 'get'), double(path: '/{id}', request_method: 'patch'), - double(path: '/a', request_method: 'get') + double(path: '/a', request_method: 'get'), + double(path: '/a.{format}', request_method: 'get') ] end @@ -30,6 +31,12 @@ expect(router.match('GET', '/c/d').error).to have_attributes(type: :not_found) end + it 'returns a match with only a request method' do + match = router.match('GET', '/a.json') + expect(match.request_definition.path).to eq('/a.{format}') + expect(match.request_definition).to be(requests[3]) + end + it 'returns an incomplete match for unknown request method' do expect(router.match('DELETE', '/b').error).to have_attributes(type: :method_not_allowed) end From 725988723e4d28a177031d24269295e7490a5c82 Mon Sep 17 00:00:00 2001 From: Jan Douwe Beekman Date: Tue, 19 Aug 2025 12:00:11 +0200 Subject: [PATCH 3/4] cleaner spec --- spec/router_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/router_spec.rb b/spec/router_spec.rb index a2cda131..5e719d29 100644 --- a/spec/router_spec.rb +++ b/spec/router_spec.rb @@ -9,7 +9,7 @@ double(path: '/{id}', request_method: 'get'), double(path: '/{id}', request_method: 'patch'), double(path: '/a', request_method: 'get'), - double(path: '/a.{format}', request_method: 'get') + double(path: '/a{format}', request_method: 'get') ] end From 77212bbe4d94b3a8b5635c165eb78660b9171118 Mon Sep 17 00:00:00 2001 From: Andreas Haller Date: Tue, 19 Aug 2025 18:40:59 +0200 Subject: [PATCH 4/4] Make code a bit more compact --- lib/openapi_first/router.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/openapi_first/router.rb b/lib/openapi_first/router.rb index d94e9ff7..5f7189fc 100644 --- a/lib/openapi_first/router.rb +++ b/lib/openapi_first/router.rb @@ -101,11 +101,11 @@ def find_path_item(request_path) params = path_item[:template].match(request_path) next unless params - [path_item, params, params.values.sum(&:length)] + [path_item, params] end + return matches.first if matches.length == 1 - matches&.min_by { |_path_item, _params, length| length } - &.then { |path_item, params, _length| [path_item, params] } + matches&.min_by { |match| match[1].values.sum(&:length) } end end end