Skip to content

Commit 15a36c5

Browse files
committed
Add OpenAPI 3 parameter deserialization with style/explode support
Fixes: #446
1 parent f1131c7 commit 15a36c5

File tree

7 files changed

+992
-5
lines changed

7 files changed

+992
-5
lines changed

lib/committee/drivers/open_api_3/driver.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ def default_validate_success_only
3333
false
3434
end
3535

36+
# Whether to deserialize parameters based on OpenAPI 3 style/explode settings
37+
def default_deserialize_parameters
38+
true
39+
end
40+
3641
def name
3742
:open_api_3
3843
end

lib/committee/errors.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,15 @@ class ReferenceNotFound < Error
3333

3434
class OpenAPI3Unsupported < Error
3535
end
36+
37+
class ParameterDeserializationError < InvalidRequest
38+
attr_reader :parameter_name, :style, :raw_value
39+
40+
def initialize(param_name, style, raw_value, message)
41+
@parameter_name = param_name
42+
@style = style
43+
@raw_value = raw_value
44+
super("Parameter '#{param_name}' (style: #{style}): #{message}")
45+
end
46+
end
3647
end

lib/committee/schema_validator/open_api_3.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,21 @@ def request_unpack(request)
9393

9494
query_param = unpacker.unpack_query_params(request)
9595
query_param.merge!(request_param) if request.get? && validator_option.allow_get_body
96+
97+
if @operation_object && validator_option.deserialize_parameters
98+
deserializer = ParameterDeserializer.new(@operation_object.request_operation)
99+
100+
query_param = deserializer.deserialize_query_params(query_param)
101+
102+
path_param = request.env[validator_option.path_hash_key]
103+
path_param = deserializer.deserialize_path_params(path_param)
104+
request.env[validator_option.path_hash_key] = path_param
105+
106+
headers = request.env[validator_option.headers_key]
107+
headers = deserializer.deserialize_headers(headers)
108+
request.env[validator_option.headers_key] = headers
109+
end
110+
96111
request.env[validator_option.query_hash_key] = query_param
97112
end
98113

@@ -116,5 +131,6 @@ def copy_coerced_data_to_params(request)
116131

117132
require_relative "open_api_3/router"
118133
require_relative "open_api_3/operation_wrapper"
134+
require_relative "open_api_3/parameter_deserializer"
119135
require_relative "open_api_3/request_validator"
120136
require_relative "open_api_3/response_validator"

lib/committee/schema_validator/open_api_3/operation_wrapper.rb

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,11 @@ def request_content_types
7070
request_operation.operation_object&.request_body&.content&.keys || []
7171
end
7272

73-
private
74-
73+
# Expose request_operation for parameter deserialization
74+
# @return [OpenAPIParser::RequestOperation]
7575
attr_reader :request_operation
7676

77-
# @!attribute [r] request_operation
78-
# @return [OpenAPIParser::RequestOperation]
77+
private
7978

8079
# @return [OpenAPIParser::SchemaValidator::Options]
8180
def build_openapi_parser_body_option(validator_option)

0 commit comments

Comments
 (0)