From 4000ce5a1a0e0066d8cb7b9778ab8126300ce136 Mon Sep 17 00:00:00 2001 From: ydah Date: Thu, 24 Sep 2026 16:20:24 +0900 Subject: [PATCH] Deserialize bracket-suffixed array query parameters --- .../open_api_3/parameter_deserializer.rb | 13 +++++++++++++ .../request_validation_open_api_3_test.rb | 14 ++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/lib/committee/schema_validator/open_api_3/parameter_deserializer.rb b/lib/committee/schema_validator/open_api_3/parameter_deserializer.rb index 2c3dbc12..99eacb32 100644 --- a/lib/committee/schema_validator/open_api_3/parameter_deserializer.rb +++ b/lib/committee/schema_validator/open_api_3/parameter_deserializer.rb @@ -116,6 +116,19 @@ def convert_to_indifferent_hash(hash) # @return [Hash] def normalize_raw_params(raw_params, location, params_for_location) return raw_params unless location == 'query' + + normalized = raw_params + params_for_location.each do |param_def| + next unless param_def.name.end_with?('[]') && param_def.schema&.type == 'array' + + raw_name = param_def.name.delete_suffix('[]') + next unless normalized[raw_name].is_a?(Array) + + normalized = raw_params.dup if normalized.equal?(raw_params) + normalized[param_def.name] = normalized.delete(raw_name) + end + + raw_params = normalized return raw_params unless raw_params.values.any? { |value| value.is_a?(Hash) } return raw_params unless requires_query_param_flattening?(params_for_location) diff --git a/test/middleware/request_validation_open_api_3_test.rb b/test/middleware/request_validation_open_api_3_test.rb index 340c662d..8b21ddbf 100644 --- a/test/middleware/request_validation_open_api_3_test.rb +++ b/test/middleware/request_validation_open_api_3_test.rb @@ -661,6 +661,20 @@ def app end describe 'bracket-style query params' do + it 'deserializes array params whose name ends with brackets' do + parameter = { 'name' => 'ids[]', 'in' => 'query', 'required' => true, 'schema' => { 'type' => 'array', 'items' => { 'type' => 'integer' } }, } + check_parameter = lambda { |env| + assert_equal [1, 2], env['committee.query_hash']['ids[]'] + assert_equal ['1', '2'], env['rack.request.query_hash']['ids'] + [200, {}, []] + } + @app = new_rack_app_with_lambda(check_parameter, schema: query_param_schema(parameter)) + + get '/events?ids[]=1&ids[]=2' + + assert_equal 200, last_response.status + end + it 'validates query params declared with bracket notation names' do check_parameter = lambda { |env| assert_equal '/test', env['committee.query_hash']['filter[slug]']