Skip to content

Commit 1a3e3f5

Browse files
authored
Allow using nicknames for body definitions (#862)
* Fix typo * Refactor MoveParams.parent_definition_of_params to use OperationId.build rather than OperationId.manipulate This means it'll use route nicknames if those are available. It also means route parameters will be used in the definition names. * Simplify MoveParams.build_body_parameter MoveParams.build_definition returns the passed in name, so name and referenced_definition were always the same value. * Fix Rubocop offenses * Fix old reference to Travis CI in CONTRIBUTING * Fix CHANGELOG * Update CHANGELOG and UPGRADING
1 parent 06975c8 commit 1a3e3f5

13 files changed

+100
-77
lines changed

CHANGELOG.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
#### Fixes
44

55
* [#850](https://github.com/ruby-grape/grape-swagger/pull/850): Fix value of `enum` to be `Array` - [@takahashim](https://github.com/takahashim)
6-
* [#846] (https://github.com/ruby-grape/grape-swagger/pull/846): Fixes oapi rake tasks, allows generating sepcs for different API versions.
6+
* [#846](https://github.com/ruby-grape/grape-swagger/pull/846): Fixes oapi rake tasks, allows generating sepcs for different API versions.
77
* [#852](https://github.com/ruby-grape/grape-swagger/pull/852): Fix example to work without error - [@takahashim](https://github.com/takahashim)
8-
* Your contribution here.
98
* [#853](https://github.com/ruby-grape/grape-swagger/pull/853): Add webrick gem so that example works in Ruby 3.x - [@takahashim](https://github.com/takahashim)
9+
* [#862](https://github.com/ruby-grape/grape-swagger/pull/862): Allow using nicknames for body definitions - [@magni-](https://github.com/magni-)
10+
* Your contribution here.
1011

1112
### 1.4.2 (October 22, 2021)
1213

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ git push origin my-feature-branch -f
115115

116116
## Check on Your Pull Request
117117

118-
Go back to your pull request after a few minutes and see whether it passed muster with Travis-CI. Everything should look green, otherwise fix issues and amend your commit as described above.
118+
Go back to your pull request after a few minutes and see whether it passed muster with GitHub Actions. Everything should look green, otherwise fix issues and amend your commit as described above.
119119

120120
## Be Patient
121121

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ ruby RUBY_VERSION
66

77
gemspec
88

9-
gem 'grape', case version = ENV['GRAPE_VERSION'] || '>= 1.5.0'
9+
gem 'grape', case version = ENV.fetch('GRAPE_VERSION', '>= 1.5.0')
1010
when 'HEAD'
1111
{ git: 'https://github.com/ruby-grape/grape' }
1212
else

UPGRADING.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
## Upgrading Grape-swagger
22

3+
### Upgrading to >= 1.5.0
4+
5+
- The names generated for body parameter definitions and their references has changed. It'll now include the HTTP action as well as any path parameters.
6+
- E.g, given a `PUT /things/:id` endpoint, `paths.things/{id}.put.parameters` in the generated Swaggerfile will contain the following:
7+
- With `grape-swagger < 1.5.0`: `{ "name": "Things", ..., "schema": { "$ref": "#/definitions/putThings" } }`
8+
- With `grape-swagger >= 1.5.0`: `{ "name": "putThingsId", ..., "schema": { "$ref": "#/definitions/putThingsId" } }`
9+
- If you use the `nickname` option for an endpoint, that nickname will be used for both the parameter name and its definition reference.
10+
- E.g., if the endpoint above were nicknamed `put-thing`, the generated Swaggerfile will contain `{ "name": "put-thing", ..., "schema": { "$ref": "#/definitions/put-thing" } }`
11+
12+
313
### Upgrading to >= 1.4.2
414

515
- `additionalProperties` has been deprecated and will be removed in a future version of `grape-swagger`. It has been replaced with `additional_properties`.

grape-swagger.gemspec

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,5 @@ Gem::Specification.new do |s|
1919
s.add_runtime_dependency 'grape', '~> 1.3'
2020

2121
s.files = `git ls-files`.split("\n")
22-
s.test_files = `git ls-files -- {test,spec}/*`.split("\n")
2322
s.require_paths = ['lib']
2423
end

lib/grape-swagger/doc_methods/move_params.rb

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,15 @@ def correct_array_param(param)
3838
end
3939

4040
def parent_definition_of_params(params, path, route)
41-
definition_name = OperationId.manipulate(parse_model(path))
42-
referenced_definition = build_definition(definition_name, params, route.request_method.downcase)
43-
definition = @definitions[referenced_definition]
41+
definition_name = OperationId.build(route, path)
42+
build_definition(definition_name, params)
43+
definition = @definitions[definition_name]
4444

4545
move_params_to_new(definition, params)
4646

4747
definition[:description] = route.description if route.try(:description)
4848

49-
build_body_parameter(referenced_definition, definition_name, route.options)
49+
build_body_parameter(definition_name, route.options)
5050
end
5151

5252
def move_params_to_new(definition, params)
@@ -142,17 +142,16 @@ def add_to_required(definition, value)
142142
definition[:required].push(*value)
143143
end
144144

145-
def build_body_parameter(reference, name, options)
145+
def build_body_parameter(name, options)
146146
{}.tap do |x|
147147
x[:name] = options[:body_name] || name
148148
x[:in] = 'body'
149149
x[:required] = true
150-
x[:schema] = { '$ref' => "#/definitions/#{reference}" }
150+
x[:schema] = { '$ref' => "#/definitions/#{name}" }
151151
end
152152
end
153153

154-
def build_definition(name, params, verb = nil)
155-
name = "#{verb}#{name}" if verb
154+
def build_definition(name, params)
156155
@definitions[name] = should_expose_as_array?(params) ? array_type : object_type
157156

158157
name

lib/grape-swagger/rake/oapi_tasks.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ def urls_for(api_class)
9898
.select { |e| e.include?('doc') }
9999
.reject { |e| e.include?(':name') }
100100
.map { |e| format_path(e) }
101-
.map { |e| [e, ENV['resource']].join('/').chomp('/') }
101+
.map { |e| [e, ENV.fetch('resource', nil)].join('/').chomp('/') }
102102
end
103103

104104
def format_path(path)

spec/issues/579_align_put_post_parameters_spec.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ class Spec < Grape::Entity
103103
[
104104
{ 'in' => 'path', 'name' => 'guid', 'type' => 'string', 'format' => 'guid', 'required' => true },
105105
{
106-
'name' => 'Issue579ImplicitBodyParameter', 'in' => 'body', 'required' => true, 'schema' => {
107-
'$ref' => '#/definitions/putIssue579ImplicitBodyParameter'
106+
'name' => 'putIssue579ImplicitBodyParameterGuid', 'in' => 'body', 'required' => true, 'schema' => {
107+
'$ref' => '#/definitions/putIssue579ImplicitBodyParameterGuid'
108108
}
109109
}
110110
]
@@ -130,8 +130,8 @@ class Spec < Grape::Entity
130130
[
131131
{ 'in' => 'path', 'name' => 'guid', 'type' => 'string', 'format' => 'guid', 'required' => true },
132132
{
133-
'name' => 'Issue579ExplicitBodyParameter', 'in' => 'body', 'required' => true, 'schema' => {
134-
'$ref' => '#/definitions/putIssue579ExplicitBodyParameter'
133+
'name' => 'putIssue579ExplicitBodyParameterGuid', 'in' => 'body', 'required' => true, 'schema' => {
134+
'$ref' => '#/definitions/putIssue579ExplicitBodyParameterGuid'
135135
}
136136
}
137137
]
@@ -157,7 +157,7 @@ class Spec < Grape::Entity
157157
[
158158
{ 'in' => 'path', 'name' => 'guid', 'type' => 'string', 'format' => 'guid', 'required' => true },
159159
{
160-
'name' => 'Issue579NamespaceParamGuidBodyParameter', 'in' => 'body', 'required' => true, 'schema' => {
160+
'name' => 'putIssue579NamespaceParamGuidBodyParameter', 'in' => 'body', 'required' => true, 'schema' => {
161161
'$ref' => '#/definitions/putIssue579NamespaceParamGuidBodyParameter'
162162
}
163163
}

spec/issues/751_deeply_nested_objects_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def self.vrp_request_service(this)
7575
end
7676

7777
describe 'Correctness of vrp Points' do
78-
let(:get_points_response) { subject['definitions']['postVrpSubmit']['properties']['vrp']['properties']['points'] }
78+
let(:get_points_response) { subject['definitions']['vrp']['properties']['vrp']['properties']['points'] }
7979
specify do
8080
expect(get_points_response).to eql(
8181
'type' => 'array',
@@ -111,7 +111,7 @@ def self.vrp_request_service(this)
111111
end
112112

113113
describe 'Correctness of vrp Services' do
114-
let(:get_service_response) { subject['definitions']['postVrpSubmit']['properties']['vrp']['properties']['services'] }
114+
let(:get_service_response) { subject['definitions']['vrp']['properties']['vrp']['properties']['services'] }
115115
specify do
116116
expect(get_service_response).to include(
117117
'type' => 'array',

spec/lib/move_params_spec.rb

Lines changed: 55 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,30 @@
103103
subject.to_definition(path, params, route, definitions)
104104
expect(params).to eql(
105105
[
106-
{ name: 'InBody', in: 'body', required: true, schema: { '$ref' => '#/definitions/postInBody' } }
106+
{ name: 'postInBody', in: 'body', required: true, schema: { '$ref' => '#/definitions/postInBody' } }
107107
]
108108
)
109109
expect(subject.definitions['postInBody']).not_to include :description
110110
expect(subject.definitions['postInBody']).to eql expected_post_defs
111111
end
112+
113+
context 'with a nickname' do
114+
let(:route_options) { { nickname: 'post-body' } }
115+
116+
specify do
117+
subject.to_definition(path, params, route, definitions)
118+
expect(params).to eql(
119+
[
120+
{ name: 'post-body', in: 'body', required: true, schema: { '$ref' => '#/definitions/post-body' } }
121+
]
122+
)
123+
expect(subject.definitions['post-body']).not_to include :description
124+
expect(subject.definitions['post-body']).to eql expected_post_defs
125+
end
126+
end
112127
end
113128

114-
describe 'POST' do
129+
describe 'PUT' do
115130
let(:params) { paths['/in_body/{key}'][:put][:parameters] }
116131
let(:route) { Grape::Router::Route.new('PUT', path.dup, **route_options) }
117132

@@ -120,12 +135,28 @@
120135
expect(params).to eql(
121136
[
122137
{ in: 'path', name: 'key', description: nil, type: 'integer', format: 'int32', required: true },
123-
{ name: 'InBody', in: 'body', required: true, schema: { '$ref' => '#/definitions/putInBody' } }
138+
{ name: 'putInBody', in: 'body', required: true, schema: { '$ref' => '#/definitions/putInBody' } }
124139
]
125140
)
126141
expect(subject.definitions['putInBody']).not_to include :description
127142
expect(subject.definitions['putInBody']).to eql expected_put_defs
128143
end
144+
145+
context 'with a nickname' do
146+
let(:route_options) { { nickname: 'put-body' } }
147+
148+
specify do
149+
subject.to_definition(path, params, route, definitions)
150+
expect(params).to eql(
151+
[
152+
{ in: 'path', name: 'key', description: nil, type: 'integer', format: 'int32', required: true },
153+
{ name: 'put-body', in: 'body', required: true, schema: { '$ref' => '#/definitions/put-body' } }
154+
]
155+
)
156+
expect(subject.definitions['put-body']).not_to include :description
157+
expect(subject.definitions['put-body']).to eql expected_put_defs
158+
end
159+
end
129160
end
130161
end
131162

@@ -167,56 +198,39 @@
167198
let(:params) { [{ in: 'body', name: 'address[street][name]', description: 'street', type: 'string', required: true }] }
168199
before do
169200
subject.instance_variable_set(:@definitions, definitions)
170-
subject.send(:build_definition, name, params, verb)
201+
subject.send(:build_definition, name, params)
171202
end
172203

173-
describe 'verb given' do
174-
let(:verb) { 'post' }
175-
let(:name) { 'Foo' }
176-
let(:definitions) { {} }
204+
let(:name) { 'FooBar' }
205+
let(:definitions) { {} }
177206

178-
specify do
179-
definition = definitions.to_a.first
180-
expect(definition.first).to eql 'postFoo'
181-
expect(definition.last).to eql(type: 'object', properties: {})
182-
end
183-
end
184-
185-
describe 'no verb given' do
186-
let(:name) { 'FooBar' }
187-
let(:definitions) { {} }
188-
let(:verb) { nil }
189-
190-
specify do
191-
definition = definitions.to_a.first
192-
expect(definition.first).to eql 'FooBar'
193-
expect(definition.last).to eql(type: 'object', properties: {})
194-
end
207+
specify do
208+
definition = definitions.to_a.first
209+
expect(definition.first).to eql 'FooBar'
210+
expect(definition.last).to eql(type: 'object', properties: {})
195211
end
196212
end
197213

198214
describe 'build_body_parameter' do
199-
describe 'name given' do
200-
let(:name) { 'Foo' }
201-
let(:reference) { 'Bar' }
215+
let(:name) { 'Foo' }
216+
let(:reference) { 'Bar' }
217+
let(:expected_param) do
218+
{ name: name, in: 'body', required: true, schema: { '$ref' => "#/definitions/#{name}" } }
219+
end
220+
specify do
221+
parameter = subject.send(:build_body_parameter, name, {})
222+
expect(parameter).to eql expected_param
223+
end
224+
225+
describe 'body_name option specified' do
226+
let(:route_options) { { body_name: 'body' } }
202227
let(:expected_param) do
203-
{ name: name, in: 'body', required: true, schema: { '$ref' => "#/definitions/#{reference}" } }
228+
{ name: route_options[:body_name], in: 'body', required: true, schema: { '$ref' => "#/definitions/#{name}" } }
204229
end
205230
specify do
206-
parameter = subject.send(:build_body_parameter, reference, name, {})
231+
parameter = subject.send(:build_body_parameter, name, route_options)
207232
expect(parameter).to eql expected_param
208233
end
209-
210-
describe 'body_name option specified' do
211-
let(:route_options) { { body_name: 'body' } }
212-
let(:expected_param) do
213-
{ name: route_options[:body_name], in: 'body', required: true, schema: { '$ref' => "#/definitions/#{reference}" } }
214-
end
215-
specify do
216-
parameter = subject.send(:build_body_parameter, reference, name, route_options)
217-
expect(parameter).to eql expected_param
218-
end
219-
end
220234
end
221235
end
222236

0 commit comments

Comments
 (0)