Response model can have required attributes (#521)
* Response model can have required attributes * Reorganize implementation * Fix RuboCop offences * Last touch of refactor
This commit is contained in:
parent
d7b7465a95
commit
7061fd1b75
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#### Features
|
||||
|
||||
* [#520](https://github.com/ruby-grape/grape-swagger/pull/520): Response model can have required attributes - [@WojciechKo](https://github.com/WojciechKo).
|
||||
* [#510](https://github.com/ruby-grape/grape-swagger/pull/510): Use 'token_owner' instead of 'oauth_token' on Swagger UI endpoint authorization. - [@texpert](https://github.com/texpert).
|
||||
* Your contribution here.
|
||||
|
||||
|
|
|
|||
|
|
@ -849,14 +849,14 @@ route_setting :x_def, [{ for: 422, other: 'stuff' }, { for: 200, some: 'stuff' }
|
|||
|
||||
Add the [grape-entity](https://github.com/ruby-grape/grape-entity) and [grape-swagger-entity](https://github.com/ruby-grape/grape-swagger-entity) gem to your Gemfile.
|
||||
|
||||
The following example exposes statuses. And exposes statuses documentation adding :type and :desc.
|
||||
The following example exposes statuses. And exposes statuses documentation adding :type, :desc and :required.
|
||||
The documented class/definition name could be set via `#entity_name`.
|
||||
|
||||
```ruby
|
||||
module API
|
||||
module Entities
|
||||
class Status < Grape::Entity
|
||||
expose :text, documentation: { type: 'string', desc: 'Status update text.' }
|
||||
expose :text, documentation: { type: 'string', desc: 'Status update text.', required: true }
|
||||
expose :links, using: Link, documentation: { type: 'link', is_array: true }
|
||||
expose :numbers, documentation: { type: 'integer', desc: 'favourite number', values: [1,2,3,4] }
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ require 'grape-swagger/doc_methods/tag_name_description'
|
|||
require 'grape-swagger/doc_methods/parse_params'
|
||||
require 'grape-swagger/doc_methods/move_params'
|
||||
require 'grape-swagger/doc_methods/headers'
|
||||
require 'grape-swagger/doc_methods/build_model_definition'
|
||||
|
||||
module GrapeSwagger
|
||||
module DocMethods
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
module GrapeSwagger
|
||||
module DocMethods
|
||||
class BuildModelDefinition
|
||||
class << self
|
||||
def build(model, properties)
|
||||
definition = { type: 'object', properties: properties }
|
||||
|
||||
required = required_attributes(model)
|
||||
definition[:required] = required unless required.blank?
|
||||
|
||||
definition
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def required_attributes(model)
|
||||
parse_entity(model) || parse_representable(model)
|
||||
end
|
||||
|
||||
def parse_entity(model)
|
||||
return unless model.respond_to?(:documentation)
|
||||
|
||||
model.documentation
|
||||
.select { |_name, options| options[:required] }
|
||||
.map { |name, options| options[:as] || name }
|
||||
end
|
||||
|
||||
def parse_representable(model)
|
||||
return unless model.respond_to?(:map)
|
||||
|
||||
model.map
|
||||
.select { |p| p[:documentation] && p[:documentation][:required] }
|
||||
.map(&:name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -291,7 +291,7 @@ module Grape
|
|||
properties = parser.new(model, self).call
|
||||
raise GrapeSwagger::Errors::SwaggerSpec, "Empty model #{model_name}, swagger 2.0 doesn't support empty definitions." unless properties && properties.any?
|
||||
|
||||
@definitions[model_name] = { type: 'object', properties: properties }
|
||||
@definitions[model_name] = GrapeSwagger::DocMethods::BuildModelDefinition.build(model, properties)
|
||||
|
||||
model_name
|
||||
end
|
||||
|
|
|
|||
|
|
@ -304,11 +304,13 @@ RSpec.shared_context 'entity swagger example' do
|
|||
'definitions' => {
|
||||
'QueryInput' => {
|
||||
'type' => 'object',
|
||||
'required' => ['elements'],
|
||||
'properties' => { 'elements' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/QueryInputElement' }, 'description' => 'Set of configuration' } },
|
||||
'description' => 'nested route inside namespace'
|
||||
},
|
||||
'QueryInputElement' => {
|
||||
'type' => 'object',
|
||||
'required' => %w(key value),
|
||||
'properties' => { 'key' => { 'type' => 'string', 'description' => 'Name of parameter' }, 'value' => { 'type' => 'string', 'description' => 'Value of parameter' } }
|
||||
},
|
||||
'ApiError' => {
|
||||
|
|
|
|||
|
|
@ -376,11 +376,13 @@ RSpec.shared_context 'representable swagger example' do
|
|||
'definitions' => {
|
||||
'QueryInput' => {
|
||||
'type' => 'object',
|
||||
'required' => ['elements'],
|
||||
'properties' => { 'elements' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/QueryInputElement' }, 'description' => 'Set of configuration' } },
|
||||
'description' => 'nested route inside namespace'
|
||||
},
|
||||
'QueryInputElement' => {
|
||||
'type' => 'object',
|
||||
'required' => %w(key value),
|
||||
'properties' => { 'key' => { 'type' => 'string', 'description' => 'Name of parameter' }, 'value' => { 'type' => 'string', 'description' => 'Value of parameter' } }
|
||||
},
|
||||
'ApiError' => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue