Skip to content

Commit c266c5b

Browse files
blakenumbata
authored andcommitted
OpenAPI3 parameters and request bodies are actually OpenAPI3 compliant
1 parent af9b11d commit c266c5b

File tree

3 files changed

+93
-20
lines changed

3 files changed

+93
-20
lines changed

lib/grape-swagger/openapi_3/doc_methods/parse_params.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,14 @@ def document_default_value(settings)
5252
end
5353

5454
def document_type_and_format(settings, data_type)
55+
@parsed_param[:schema] = {}
5556
if DataType.primitive?(data_type)
5657
data = DataType.mapping(data_type)
57-
@parsed_param[:type], @parsed_param[:format] = data
58+
@parsed_param[:schema][:type], @parsed_param[:schema][:format] = data
5859
else
59-
@parsed_param[:type] = data_type
60+
@parsed_param[:schema][:type] = data_type
6061
end
61-
@parsed_param[:format] = settings[:format] if settings[:format].present?
62+
@parsed_param[:schema][:format] = settings[:format] if settings[:format].present?
6263
end
6364

6465
def document_array_param(value_type, definitions)

lib/grape-swagger/openapi_3/endpoint.rb

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,15 @@ def method_object(route, options, path)
117117
method = {}
118118
method[:summary] = summary_object(route)
119119
method[:description] = description_object(route)
120-
method[:parameters] = params_object(route, options, path)
120+
121+
parameters = params_object(route, options, path).partition { |p| p[:in] == 'body' || p[:in] == 'formData' }
122+
123+
method[:parameters] = parameters.last
121124
method[:security] = security_object(route)
122125
if %w[POST PUT PATCH].include?(route.request_method)
123-
method[:requestBody] = response_body_object(route, options, path)
126+
method[:requestBody] = response_body_object(route, path, parameters.first)
124127
end
125128

126-
# method[:consumes] = consumes_object(route, options[:format])
127129
produces = produces_object(route, options[:produces] || options[:format])
128130

129131
method[:responses] = response_object(route, produces)
@@ -200,28 +202,17 @@ def params_object(route, options, path)
200202
parameters
201203
end
202204

203-
def response_body_object(route, options, path)
204-
parameters = partition_params(route, options).map do |param, value|
205-
value = { required: false }.merge(value) if value.is_a?(Hash)
206-
_, value = default_type([[param, value]]).first if value == ''
207-
if value[:type]
208-
expose_params(value[:type])
209-
elsif value[:documentation]
210-
expose_params(value[:documentation][:type])
211-
end
212-
213-
GrapeSwagger::DocMethods::ParseRequestBody.call(param, value, path, route, @definitions)
214-
end.flatten
215-
205+
def response_body_object(_, _, parameters)
216206
parameters = {
217207
'content' => parameters.group_by { |p| p[:in] }.map do |_k, v|
208+
properties = v.map { |value| [value[:name], value.except(:name, :in, :required, :schema).merge(value[:schema])] }.to_h
218209
required_values = v.select { |param| param[:required] }
219210
[
220211
'application/x-www-form-urlencoded',
221212
{ 'schema' => {
222213
'type' => 'object',
223214
'required' => required_values.map { |required| required[:name] },
224-
'properties' => v.map { |value| [value[:name], value.except(:name, :in, :required)] }.to_h
215+
'properties' => properties
225216
} }
226217
]
227218
end.to_h
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# frozen_string_literal: true
2+
3+
require 'spec_helper'
4+
5+
describe 'Params Multi Types' do
6+
def app
7+
Class.new(Grape::API) do
8+
format :json
9+
10+
params do
11+
if Grape::VERSION < '0.14'
12+
requires :input, type: [String, Integer]
13+
else
14+
requires :input, types: [String, Integer]
15+
end
16+
requires :another_input, type: [String, Integer]
17+
end
18+
post :action do
19+
end
20+
21+
add_swagger_documentation openapi_version: '3.0'
22+
end
23+
end
24+
25+
subject do
26+
get '/swagger_doc/action'
27+
expect(last_response.status).to eq 200
28+
body = JSON.parse last_response.body
29+
body['paths']['/action']['post']
30+
end
31+
32+
it 'reads request body type correctly' do
33+
expect(subject['requestBody']['content']).to eq('application/x-www-form-urlencoded' => {
34+
'schema' => {
35+
'properties' => { 'another_input' => { 'type' => 'string' }, 'input' => { 'type' => 'string' } },
36+
'required' => %w[input another_input],
37+
'type' => 'object'
38+
}
39+
})
40+
end
41+
42+
describe 'header params' do
43+
def app
44+
Class.new(Grape::API) do
45+
format :json
46+
47+
desc 'Some API', headers: { 'My-Header' => { required: true, description: 'Set this!' } }
48+
params do
49+
if Grape::VERSION < '0.14'
50+
requires :input, type: [String, Integer]
51+
else
52+
requires :input, types: [String, Integer]
53+
end
54+
requires :another_input, type: [String, Integer]
55+
end
56+
post :action do
57+
end
58+
59+
add_swagger_documentation openapi_version: '3.0'
60+
end
61+
end
62+
63+
it 'reads parameter type correctly' do
64+
expect(subject['parameters']).to eq([{
65+
'description' => 'Set this!',
66+
'in' => 'header',
67+
'name' => 'My-Header',
68+
'required' => true,
69+
'schema' => { 'type' => 'string' }
70+
}])
71+
end
72+
73+
it 'has consistent types' do
74+
request_body_types = subject['requestBody']['content']['application/x-www-form-urlencoded']['schema']['properties'].values.map { |param| param['type'] }
75+
expect(request_body_types).to eq(%w[string string])
76+
77+
request_body_types = subject['parameters'].map { |param| param['schema']['type'] }
78+
expect(request_body_types).to eq(%w[string])
79+
end
80+
end
81+
end

0 commit comments

Comments
 (0)