diff --git a/CHANGELOG.md b/CHANGELOG.md index af9c5185..3ccdfb09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ #### Fixes +* [#540](https://github.com/ruby-grape/grape-swagger/pull/540): Corrects exposing of array in post body - [@LeFnord](https://github.com/LeFnord). * [#509](https://github.com/ruby-grape/grape-swagger/pull/509), [#529](https://github.com/ruby-grape/grape-swagger/pull/529): Making parent-less routes working - [@mur-wtag](https://github.com/mur-wtag). * Your contribution here. diff --git a/README.md b/README.md index b6c9ad46..476380d3 100644 --- a/README.md +++ b/README.md @@ -956,7 +956,7 @@ module API class Client < Grape::Entity expose :name, documentation: { type: 'string', desc: 'Name' } expose :addresses, using: Entities::Address, - documentation: { type: 'API::Address', desc: 'Addresses.', param_type: 'body', is_array: true } + documentation: { type: 'Entities::Address', desc: 'Addresses.', param_type: 'body', is_array: true } end class Address < Grape::Entity @@ -967,13 +967,15 @@ module API class Clients < Grape::API version 'v1' - desc 'Clients index', params: Entities::Client.documentation + desc 'Clients index', + params: Entities::Client.documentation, + success: Entities::Client get '/clients' do ... end end - add_swagger_documentation models: [Entities::Client, Entities::Address] + add_swagger_documentation end ``` @@ -988,7 +990,7 @@ module API class Client < Grape::Entity expose :name, documentation: { type: 'string', desc: 'Name' } expose :address, using: Entities::Address, - documentation: { type: 'API::Address', desc: 'Addresses.', param_type: 'body', is_array: false } + documentation: { type: 'Entities::Address', desc: 'Addresses.', param_type: 'body', is_array: false } end class Address < Grape::Entity @@ -999,13 +1001,15 @@ module API class Clients < Grape::API version 'v1' - desc 'Clients index', params: Entities::Client.documentation + desc 'Clients index', + params: Entities::Client.documentation, + success: Entities::Client get '/clients' do ... end end - add_swagger_documentation models: [Entities::Client, Entities::Address] + add_swagger_documentation end ``` diff --git a/lib/grape-swagger/doc_methods/move_params.rb b/lib/grape-swagger/doc_methods/move_params.rb index 9c7828ac..4d66fecb 100644 --- a/lib/grape-swagger/doc_methods/move_params.rb +++ b/lib/grape-swagger/doc_methods/move_params.rb @@ -12,6 +12,8 @@ def to_definition(params, route, definitions) @definitions = definitions unify!(params) + return correct_array_param(params) if should_correct_array?(params) + params_to_move = movable_params(params) params << parent_definition_of_params(params_to_move, route) @@ -20,6 +22,14 @@ def to_definition(params, route, definitions) private + def should_correct_array?(param) + param.length == 1 && param.first[:in] == 'body' && param.first[:type] == 'array' + end + + def correct_array_param(param) + param.first[:schema] = { type: param.first.delete(:type), items: param.first.delete(:items) } + end + def parent_definition_of_params(params, route) definition_name = GrapeSwagger::DocMethods::OperationId.manipulate(parse_model(route.path)) referenced_definition = build_definition(definition_name, params, route.request_method.downcase) diff --git a/lib/grape-swagger/doc_methods/parse_params.rb b/lib/grape-swagger/doc_methods/parse_params.rb index f5326d99..80119d6c 100644 --- a/lib/grape-swagger/doc_methods/parse_params.rb +++ b/lib/grape-swagger/doc_methods/parse_params.rb @@ -68,6 +68,8 @@ def document_array_param(value_type, definitions) collection_format = value_type[:documentation][:collectionFormat] end + param_type ||= value_type[:param_type] + array_items = {} if definitions[value_type[:data_type]] array_items['$ref'] = "#/definitions/#{@parsed_param[:type]}" diff --git a/spec/issues/539_array_post_body.rb b/spec/issues/539_array_post_body.rb new file mode 100644 index 00000000..cb8cecbc --- /dev/null +++ b/spec/issues/539_array_post_body.rb @@ -0,0 +1,63 @@ +require 'spec_helper' +require 'grape-entity' +require 'grape-swagger-entity' + +describe '#427 nested entity given as string' do + let(:app) do + Class.new(Grape::API) do + namespace :issue_427 do + class Element < Grape::Entity + expose :id + expose :description + expose :role + end + + class ArrayOfElements < Grape::Entity + expose :elements, + documentation: { + type: ::Element, is_array: true, param_type: 'body', required: true + } + end + + desc 'create account', + params: ArrayOfElements.documentation + post do + present params + end + end + + add_swagger_documentation format: :json + end + end + + subject do + get '/swagger_doc' + JSON.parse(last_response.body) + end + + let(:parameters) { subject['paths']['/issue_427']['post']['parameters'] } + let(:definitions) { subject['definitions'] } + + specify do + expect(parameters).to eql( + [ + { + 'in' => 'body', 'name' => 'elements', 'required' => true, 'schema' => { + 'type' => 'array', 'items' => { '$ref' => '#/definitions/Element' } + } + } + ] + ) + + expect(definitions).to eql( + 'Element' => { + 'type' => 'object', + 'properties' => { + 'id' => { 'type' => 'string' }, + 'description' => { 'type' => 'string' }, + 'role' => { 'type' => 'string' } + } + } + ) + end +end