apipie-rails 0.5.7 → 0.5.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/PROPOSAL_FOR_RESPONSE_DESCRIPTIONS.md +244 -0
- data/README.rst +320 -2
- data/lib/apipie-rails.rb +2 -0
- data/lib/apipie/application.rb +1 -1
- data/lib/apipie/configuration.rb +5 -2
- data/lib/apipie/dsl_definition.rb +69 -1
- data/lib/apipie/errors.rb +6 -1
- data/lib/apipie/extractor/writer.rb +65 -42
- data/lib/apipie/method_description.rb +32 -2
- data/lib/apipie/param_description.rb +19 -1
- data/lib/apipie/resource_description.rb +3 -1
- data/lib/apipie/response_description.rb +125 -0
- data/lib/apipie/response_description_adapter.rb +199 -0
- data/lib/apipie/swagger_generator.rb +106 -16
- data/lib/apipie/version.rb +1 -1
- data/spec/controllers/apipies_controller_spec.rb +1 -0
- data/spec/dummy/app/controllers/application_controller.rb +4 -0
- data/spec/dummy/app/controllers/pets_controller.rb +391 -0
- data/spec/dummy/app/controllers/pets_using_auto_views_controller.rb +73 -0
- data/spec/dummy/app/controllers/pets_using_self_describing_classes_controller.rb +95 -0
- data/spec/lib/extractor/writer_spec.rb +32 -4
- data/spec/lib/method_description_spec.rb +27 -0
- data/spec/lib/swagger/rake_swagger_spec.rb +4 -0
- data/spec/lib/swagger/swagger_dsl_spec.rb +489 -0
- data/spec/spec_helper.rb +94 -0
- metadata +13 -2
data/lib/apipie-rails.rb
CHANGED
@@ -12,6 +12,8 @@ require "apipie/resource_description"
|
|
12
12
|
require "apipie/param_description"
|
13
13
|
require "apipie/errors"
|
14
14
|
require "apipie/error_description"
|
15
|
+
require "apipie/response_description"
|
16
|
+
require "apipie/response_description_adapter"
|
15
17
|
require "apipie/see_description"
|
16
18
|
require "apipie/validator"
|
17
19
|
require "apipie/railtie"
|
data/lib/apipie/application.rb
CHANGED
@@ -55,7 +55,7 @@ module Apipie
|
|
55
55
|
# this method does in depth search for the route controller
|
56
56
|
def route_app_controller(app, route, visited_apps = [])
|
57
57
|
if route.defaults[:controller]
|
58
|
-
controller_name =
|
58
|
+
controller_name = "#{route.defaults[:controller]}_controller".camelize
|
59
59
|
controller_name.safe_constantize
|
60
60
|
end
|
61
61
|
end
|
data/lib/apipie/configuration.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
module Apipie
|
2
2
|
class Configuration
|
3
3
|
|
4
|
-
attr_accessor :app_name, :app_info, :copyright, :
|
4
|
+
attr_accessor :app_name, :app_info, :copyright, :compress_examples,
|
5
|
+
:markup, :disqus_shortname,
|
5
6
|
:api_base_url, :doc_base_url, :required_by_default, :layout,
|
6
7
|
:default_version, :debug, :version_in_url, :namespaced_resources,
|
7
8
|
:validate, :validate_value, :validate_presence, :validate_key, :authenticate, :doc_path,
|
@@ -9,7 +10,8 @@ module Apipie
|
|
9
10
|
:link_extension, :record, :languages, :translate, :locale, :default_locale,
|
10
11
|
:persist_show_in_doc, :authorize,
|
11
12
|
:swagger_include_warning_tags, :swagger_content_type_input, :swagger_json_input_uses_refs,
|
12
|
-
:swagger_suppress_warnings, :swagger_api_host, :swagger_generate_x_computed_id_field
|
13
|
+
:swagger_suppress_warnings, :swagger_api_host, :swagger_generate_x_computed_id_field,
|
14
|
+
:swagger_allow_additional_properties_in_response
|
13
15
|
|
14
16
|
alias_method :validate?, :validate
|
15
17
|
alias_method :required_by_default?, :required_by_default
|
@@ -176,6 +178,7 @@ module Apipie
|
|
176
178
|
@swagger_suppress_warnings = false #[105,100,102]
|
177
179
|
@swagger_api_host = "localhost:3000"
|
178
180
|
@swagger_generate_x_computed_id_field = false
|
181
|
+
@swagger_allow_additional_properties_in_response = false
|
179
182
|
end
|
180
183
|
end
|
181
184
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Apipie
|
4
4
|
|
5
|
-
# DSL is a module that provides #api, #error, #param, #
|
5
|
+
# DSL is a module that provides #api, #error, #param, #returns.
|
6
6
|
module DSL
|
7
7
|
|
8
8
|
module Base
|
@@ -32,6 +32,7 @@ module Apipie
|
|
32
32
|
:api_args => [],
|
33
33
|
:api_from_routes => nil,
|
34
34
|
:errors => [],
|
35
|
+
:returns => {},
|
35
36
|
:params => [],
|
36
37
|
:headers => [],
|
37
38
|
:resource_id => nil,
|
@@ -309,6 +310,7 @@ module Apipie
|
|
309
310
|
end
|
310
311
|
end
|
311
312
|
|
313
|
+
|
312
314
|
# this describes the params, it's in separate module because it's
|
313
315
|
# used in Validators as well
|
314
316
|
module Param
|
@@ -329,6 +331,13 @@ module Apipie
|
|
329
331
|
block]
|
330
332
|
end
|
331
333
|
|
334
|
+
def property(param_name, validator, desc_or_options = nil, options = {}, &block) #:doc:
|
335
|
+
return unless Apipie.active_dsl?
|
336
|
+
options[:only_in] ||= :response
|
337
|
+
options[:required] = true if options[:required].nil?
|
338
|
+
param(param_name, validator, desc_or_options, options, &block)
|
339
|
+
end
|
340
|
+
|
332
341
|
# Reuses param group for this method. The definition is looked up
|
333
342
|
# in scope of this controller. If the group was defined in
|
334
343
|
# different controller, the second param can be used to specify it.
|
@@ -354,6 +363,65 @@ module Apipie
|
|
354
363
|
@_current_param_group = nil
|
355
364
|
end
|
356
365
|
|
366
|
+
# Describe possible responses
|
367
|
+
#
|
368
|
+
# Example:
|
369
|
+
# def_param_group :user do
|
370
|
+
# param :user, Hash do
|
371
|
+
# param :name, String
|
372
|
+
# end
|
373
|
+
# end
|
374
|
+
#
|
375
|
+
# returns :user, "the speaker"
|
376
|
+
# returns "the speaker" do
|
377
|
+
# param_group: :user
|
378
|
+
# end
|
379
|
+
# returns :param_group => :user, "the speaker"
|
380
|
+
# returns :user, :code => 201, :desc => "the created speaker record"
|
381
|
+
# returns :array_of => :user, "many speakers"
|
382
|
+
# def hello_world
|
383
|
+
# render json: {user: {name: "Alfred"}}
|
384
|
+
# end
|
385
|
+
#
|
386
|
+
def returns(pgroup_or_options, desc_or_options=nil, options={}, &block) #:doc:
|
387
|
+
return unless Apipie.active_dsl?
|
388
|
+
|
389
|
+
|
390
|
+
if desc_or_options.is_a? Hash
|
391
|
+
options.merge!(desc_or_options)
|
392
|
+
elsif !desc_or_options.nil?
|
393
|
+
options[:desc] = desc_or_options
|
394
|
+
end
|
395
|
+
|
396
|
+
if pgroup_or_options.is_a? Hash
|
397
|
+
options.merge!(pgroup_or_options)
|
398
|
+
else
|
399
|
+
options[:param_group] = pgroup_or_options
|
400
|
+
end
|
401
|
+
|
402
|
+
code = options[:code] || 200
|
403
|
+
scope = options[:scope] || _default_param_group_scope
|
404
|
+
descriptor = options[:param_group] || options[:array_of]
|
405
|
+
|
406
|
+
if block.nil?
|
407
|
+
if descriptor.is_a? ResponseDescriptionAdapter
|
408
|
+
adapter = descriptor
|
409
|
+
elsif descriptor.respond_to? :describe_own_properties
|
410
|
+
adapter = ResponseDescriptionAdapter.from_self_describing_class(descriptor)
|
411
|
+
else
|
412
|
+
begin
|
413
|
+
block = Apipie.get_param_group(scope, descriptor) if descriptor
|
414
|
+
rescue
|
415
|
+
raise "No param_group or self-describing class named #{descriptor}"
|
416
|
+
end
|
417
|
+
end
|
418
|
+
elsif descriptor
|
419
|
+
raise "cannot specify both block and param_group"
|
420
|
+
end
|
421
|
+
|
422
|
+
_apipie_dsl_data[:returns][code] = [options, scope, block, adapter]
|
423
|
+
end
|
424
|
+
|
357
425
|
# where the group definition should be looked up when no scope
|
358
426
|
# given. This is expected to return a controller.
|
359
427
|
def _default_param_group_scope
|
data/lib/apipie/errors.rb
CHANGED
@@ -9,6 +9,12 @@ module Apipie
|
|
9
9
|
class UnknownCode < Error
|
10
10
|
end
|
11
11
|
|
12
|
+
class ReturnsMultipleDefinitionError < Error
|
13
|
+
def to_s
|
14
|
+
"a 'returns' statement cannot indicate both array_of and type"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
12
18
|
# abstract
|
13
19
|
class DefinedParamError < ParamError
|
14
20
|
attr_accessor :param
|
@@ -51,5 +57,4 @@ module Apipie
|
|
51
57
|
"Invalid parameter '#{@param}' value #{@value.inspect}: #{@error}"
|
52
58
|
end
|
53
59
|
end
|
54
|
-
|
55
60
|
end
|
@@ -3,11 +3,76 @@ require 'set'
|
|
3
3
|
module Apipie
|
4
4
|
module Extractor
|
5
5
|
class Writer
|
6
|
+
class << self
|
7
|
+
def compressed
|
8
|
+
Apipie.configuration.compress_examples
|
9
|
+
end
|
10
|
+
|
11
|
+
def update_action_description(controller, action)
|
12
|
+
updater = ActionDescriptionUpdater.new(controller, action)
|
13
|
+
yield updater
|
14
|
+
updater.write!
|
15
|
+
rescue ActionDescriptionUpdater::ControllerNotFound
|
16
|
+
logger.warn("REST_API: Couldn't find controller file for #{controller}")
|
17
|
+
rescue ActionDescriptionUpdater::ActionNotFound
|
18
|
+
logger.warn("REST_API: Couldn't find action #{action} in #{controller}")
|
19
|
+
end
|
20
|
+
|
21
|
+
def write_recorded_examples(examples)
|
22
|
+
FileUtils.mkdir_p(File.dirname(examples_file))
|
23
|
+
content = serialize_examples(examples)
|
24
|
+
content = Zlib::Deflate.deflate(content).force_encoding('utf-8') if compressed
|
25
|
+
File.open(examples_file, 'w') { |f| f << content }
|
26
|
+
end
|
27
|
+
|
28
|
+
def load_recorded_examples
|
29
|
+
return {} unless File.exist?(examples_file)
|
30
|
+
load_json_examples
|
31
|
+
end
|
32
|
+
|
33
|
+
def examples_file
|
34
|
+
pure_path = Rails.root.join(
|
35
|
+
Apipie.configuration.doc_path, 'apipie_examples.json'
|
36
|
+
)
|
37
|
+
zipped_path = pure_path.to_s + '.gz'
|
38
|
+
return zipped_path if compressed
|
39
|
+
pure_path.to_s
|
40
|
+
end
|
41
|
+
|
42
|
+
protected
|
43
|
+
|
44
|
+
def serialize_examples(examples)
|
45
|
+
JSON.pretty_generate(
|
46
|
+
OrderedHash[*examples.sort_by(&:first).flatten(1)]
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
def deserialize_examples(examples_string)
|
51
|
+
examples = JSON.parse(examples_string)
|
52
|
+
return {} if examples.nil?
|
53
|
+
examples.each_value do |records|
|
54
|
+
records.each do |record|
|
55
|
+
record['verb'] = record['verb'].to_sym if record['verb']
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def load_json_examples
|
61
|
+
raw = IO.read(examples_file)
|
62
|
+
raw = Zlib::Inflate.inflate(raw).force_encoding('utf-8') if compressed
|
63
|
+
deserialize_examples(raw)
|
64
|
+
end
|
65
|
+
|
66
|
+
def logger
|
67
|
+
Extractor.logger
|
68
|
+
end
|
69
|
+
end
|
6
70
|
|
7
71
|
def initialize(collector)
|
8
72
|
@collector = collector
|
9
73
|
end
|
10
74
|
|
75
|
+
|
11
76
|
def write_examples
|
12
77
|
merged_examples = merge_old_new_examples
|
13
78
|
self.class.write_recorded_examples(merged_examples)
|
@@ -26,47 +91,9 @@ module Apipie
|
|
26
91
|
end
|
27
92
|
end
|
28
93
|
|
29
|
-
def self.update_action_description(controller, action)
|
30
|
-
updater = ActionDescriptionUpdater.new(controller, action)
|
31
|
-
yield updater
|
32
|
-
updater.write!
|
33
|
-
rescue ActionDescriptionUpdater::ControllerNotFound
|
34
|
-
logger.warn("REST_API: Couldn't find controller file for #{controller}")
|
35
|
-
rescue ActionDescriptionUpdater::ActionNotFound
|
36
|
-
logger.warn("REST_API: Couldn't find action #{action} in #{controller}")
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.write_recorded_examples(examples)
|
40
|
-
examples_file = self.examples_file
|
41
|
-
FileUtils.mkdir_p(File.dirname(examples_file))
|
42
|
-
File.open(examples_file, "w") do |f|
|
43
|
-
f << JSON.pretty_generate(OrderedHash[*examples.sort_by(&:first).flatten(1)])
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def self.load_recorded_examples
|
48
|
-
examples_file = self.examples_file
|
49
|
-
if File.exists?(examples_file)
|
50
|
-
return load_json_examples
|
51
|
-
end
|
52
|
-
return {}
|
53
|
-
end
|
54
|
-
|
55
|
-
def self.examples_file
|
56
|
-
File.join(Rails.root,Apipie.configuration.doc_path,"apipie_examples.json")
|
57
|
-
end
|
58
94
|
|
59
95
|
protected
|
60
96
|
|
61
|
-
def self.load_json_examples
|
62
|
-
examples = JSON.load(IO.read(examples_file))
|
63
|
-
return {} if examples.nil?
|
64
|
-
examples.each do |method, records|
|
65
|
-
records.each do |record|
|
66
|
-
record["verb"] = record["verb"].to_sym if record["verb"]
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
97
|
|
71
98
|
def desc_to_s(description)
|
72
99
|
"#{description[:controller].name}##{description[:action]}"
|
@@ -177,10 +204,6 @@ module Apipie
|
|
177
204
|
self.class.logger
|
178
205
|
end
|
179
206
|
|
180
|
-
def self.logger
|
181
|
-
Extractor.logger
|
182
|
-
end
|
183
|
-
|
184
207
|
def showable_in_doc?(call)
|
185
208
|
# we don't want to mess documentation with too large examples
|
186
209
|
if hash_nodes_count(call["request_data"]) + hash_nodes_count(call["response_data"]) > 100
|
@@ -5,7 +5,7 @@ module Apipie
|
|
5
5
|
|
6
6
|
class Api
|
7
7
|
|
8
|
-
attr_accessor :short_description, :path, :http_method, :from_routes, :options
|
8
|
+
attr_accessor :short_description, :path, :http_method, :from_routes, :options, :returns
|
9
9
|
|
10
10
|
def initialize(method, path, desc, options)
|
11
11
|
@http_method = method.to_s
|
@@ -34,6 +34,10 @@ module Apipie
|
|
34
34
|
Apipie::ErrorDescription.from_dsl_data(args)
|
35
35
|
end
|
36
36
|
|
37
|
+
@returns = dsl_data[:returns].map do |code,args|
|
38
|
+
Apipie::ResponseDescription.from_dsl_data(self, code, args)
|
39
|
+
end
|
40
|
+
|
37
41
|
@see = dsl_data[:see].map do |args|
|
38
42
|
Apipie::SeeDescription.new(args)
|
39
43
|
end
|
@@ -46,7 +50,8 @@ module Apipie
|
|
46
50
|
|
47
51
|
@params_ordered = dsl_data[:params].map do |args|
|
48
52
|
Apipie::ParamDescription.from_dsl_data(self, args)
|
49
|
-
end
|
53
|
+
end.reject{|p| p.response_only? }
|
54
|
+
|
50
55
|
@params_ordered = ParamDescription.unify(@params_ordered)
|
51
56
|
@headers = dsl_data[:headers]
|
52
57
|
|
@@ -85,6 +90,25 @@ module Apipie
|
|
85
90
|
all_params.find_all(&:validator)
|
86
91
|
end
|
87
92
|
|
93
|
+
def returns_self
|
94
|
+
@returns
|
95
|
+
end
|
96
|
+
|
97
|
+
def returns
|
98
|
+
all_returns = []
|
99
|
+
parent = Apipie.get_resource_description(@resource.controller.superclass)
|
100
|
+
|
101
|
+
# get response descriptions from parent resource description
|
102
|
+
[parent, @resource].compact.each do |resource|
|
103
|
+
resource_returns = resource._returns_args.map do |code, args|
|
104
|
+
Apipie::ResponseDescription.from_dsl_data(self, code, args)
|
105
|
+
end
|
106
|
+
merge_returns(all_returns, resource_returns)
|
107
|
+
end
|
108
|
+
|
109
|
+
merge_returns(all_returns, @returns)
|
110
|
+
end
|
111
|
+
|
88
112
|
def errors
|
89
113
|
return @merged_errors if @merged_errors
|
90
114
|
@merged_errors = []
|
@@ -189,6 +213,12 @@ module Apipie
|
|
189
213
|
params.concat(new_params)
|
190
214
|
end
|
191
215
|
|
216
|
+
def merge_returns(returns, new_returns)
|
217
|
+
new_return_codes = Set.new(new_returns.map(&:code))
|
218
|
+
returns.delete_if { |p| new_return_codes.include?(p.code) }
|
219
|
+
returns.concat(new_returns)
|
220
|
+
end
|
221
|
+
|
192
222
|
def load_recorded_examples
|
193
223
|
(Apipie.recorded_examples[id] || []).
|
194
224
|
find_all { |ex| ex["show_in_doc"].to_i > 0 }.
|
@@ -8,9 +8,14 @@ module Apipie
|
|
8
8
|
# validator - Validator::BaseValidator subclass
|
9
9
|
class ParamDescription
|
10
10
|
|
11
|
-
attr_reader :method_description, :name, :desc, :allow_nil, :allow_blank, :validator, :options, :metadata, :show, :as, :validations
|
11
|
+
attr_reader :method_description, :name, :desc, :allow_nil, :allow_blank, :validator, :options, :metadata, :show, :as, :validations, :response_only, :request_only
|
12
|
+
attr_reader :additional_properties, :is_array
|
12
13
|
attr_accessor :parent, :required
|
13
14
|
|
15
|
+
alias_method :response_only?, :response_only
|
16
|
+
alias_method :request_only?, :request_only
|
17
|
+
alias_method :is_array?, :is_array
|
18
|
+
|
14
19
|
def self.from_dsl_data(method_description, args)
|
15
20
|
param_name, validator, desc_or_options, options, block = args
|
16
21
|
Apipie::ParamDescription.new(method_description,
|
@@ -62,6 +67,10 @@ module Apipie
|
|
62
67
|
|
63
68
|
@required = is_required?
|
64
69
|
|
70
|
+
@response_only = (@options[:only_in] == :response)
|
71
|
+
@request_only = (@options[:only_in] == :request)
|
72
|
+
raise ArgumentError.new("'#{@options[:only_in]}' is not a valid value for :only_in") if (!@response_only && !@request_only) && @options[:only_in].present?
|
73
|
+
|
65
74
|
@show = if @options.has_key? :show
|
66
75
|
@options[:show]
|
67
76
|
else
|
@@ -74,11 +83,20 @@ module Apipie
|
|
74
83
|
action_awareness
|
75
84
|
|
76
85
|
if validator
|
86
|
+
if (validator != Hash) && (validator.is_a? Hash) && (validator[:array_of])
|
87
|
+
@is_array = true
|
88
|
+
rest_of_options = validator
|
89
|
+
validator = validator[:array_of]
|
90
|
+
options.merge!(rest_of_options.select{|k,v| k != :array_of })
|
91
|
+
raise "an ':array_of =>' validator is allowed exclusively on response-only fields" unless @response_only
|
92
|
+
end
|
77
93
|
@validator = Validator::BaseValidator.find(self, validator, @options, block)
|
78
94
|
raise "Validator for #{validator} not found." unless @validator
|
79
95
|
end
|
80
96
|
|
81
97
|
@validations = Array(options[:validations]).map {|v| concern_subst(Apipie.markup_to_html(v)) }
|
98
|
+
|
99
|
+
@additional_properties = @options[:additional_properties]
|
82
100
|
end
|
83
101
|
|
84
102
|
def from_concern?
|
@@ -14,7 +14,7 @@ module Apipie
|
|
14
14
|
class ResourceDescription
|
15
15
|
|
16
16
|
attr_reader :controller, :_short_description, :_full_description, :_methods, :_id,
|
17
|
-
:_path, :_name, :_params_args, :_errors_args, :_formats, :_parent, :_metadata,
|
17
|
+
:_path, :_name, :_params_args, :_returns_args, :_errors_args, :_formats, :_parent, :_metadata,
|
18
18
|
:_headers, :_deprecated
|
19
19
|
|
20
20
|
def initialize(controller, resource_name, dsl_data = nil, version = nil, &block)
|
@@ -22,6 +22,7 @@ module Apipie
|
|
22
22
|
@_methods = ActiveSupport::OrderedHash.new
|
23
23
|
@_params_args = []
|
24
24
|
@_errors_args = []
|
25
|
+
@_returns_args = []
|
25
26
|
|
26
27
|
@controller = controller
|
27
28
|
@_id = resource_name
|
@@ -40,6 +41,7 @@ module Apipie
|
|
40
41
|
@_formats = dsl_data[:formats]
|
41
42
|
@_errors_args = dsl_data[:errors]
|
42
43
|
@_params_args = dsl_data[:params]
|
44
|
+
@_returns_args = dsl_data[:returns]
|
43
45
|
@_metadata = dsl_data[:meta]
|
44
46
|
@_api_base_url = dsl_data[:api_base_url]
|
45
47
|
@_headers = dsl_data[:headers]
|
@@ -0,0 +1,125 @@
|
|
1
|
+
module Apipie
|
2
|
+
|
3
|
+
class ResponseDescription
|
4
|
+
class ResponseObject
|
5
|
+
include Apipie::DSL::Base
|
6
|
+
include Apipie::DSL::Param
|
7
|
+
|
8
|
+
attr_accessor :additional_properties
|
9
|
+
|
10
|
+
def initialize(method_description, scope, block)
|
11
|
+
@method_description = method_description
|
12
|
+
@scope = scope
|
13
|
+
@param_group = {scope: scope}
|
14
|
+
@additional_properties = false
|
15
|
+
|
16
|
+
self.instance_exec(&block) if block
|
17
|
+
|
18
|
+
prepare_hash_params
|
19
|
+
end
|
20
|
+
|
21
|
+
# this routine overrides Param#_default_param_group_scope and is called if Param#param_group is
|
22
|
+
# invoked during the instance_exec call in ResponseObject#initialize
|
23
|
+
def _default_param_group_scope
|
24
|
+
@scope
|
25
|
+
end
|
26
|
+
|
27
|
+
def name
|
28
|
+
"response #{@code} for #{@method_description.method}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def params_ordered
|
32
|
+
@params_ordered ||= _apipie_dsl_data[:params].map do |args|
|
33
|
+
options = args.find { |arg| arg.is_a? Hash }
|
34
|
+
options[:param_group] = @param_group
|
35
|
+
Apipie::ParamDescription.from_dsl_data(@method_description, args) unless options[:only_in] == :request
|
36
|
+
end.compact
|
37
|
+
end
|
38
|
+
|
39
|
+
def prepare_hash_params
|
40
|
+
@hash_params = params_ordered.reduce({}) do |h, param|
|
41
|
+
h.update(param.name.to_sym => param)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
class ResponseDescription
|
50
|
+
include Apipie::DSL::Base
|
51
|
+
include Apipie::DSL::Param
|
52
|
+
|
53
|
+
attr_reader :code, :description, :scope, :type_ref, :hash_validator, :is_array_of
|
54
|
+
|
55
|
+
def self.from_dsl_data(method_description, code, args)
|
56
|
+
options, scope, block, adapter = args
|
57
|
+
|
58
|
+
Apipie::ResponseDescription.new(method_description,
|
59
|
+
code,
|
60
|
+
options,
|
61
|
+
scope,
|
62
|
+
block,
|
63
|
+
adapter)
|
64
|
+
end
|
65
|
+
|
66
|
+
def is_array?
|
67
|
+
@is_array_of != false
|
68
|
+
end
|
69
|
+
|
70
|
+
def initialize(method_description, code, options, scope, block, adapter)
|
71
|
+
|
72
|
+
@type_ref = options[:param_group]
|
73
|
+
@is_array_of = options[:array_of] || false
|
74
|
+
raise ReturnsMultipleDefinitionError, options if @is_array_of && @type_ref
|
75
|
+
|
76
|
+
@type_ref ||= @is_array_of
|
77
|
+
|
78
|
+
@method_description = method_description
|
79
|
+
|
80
|
+
if code.is_a? Symbol
|
81
|
+
@code = Rack::Utils::SYMBOL_TO_STATUS_CODE[code]
|
82
|
+
else
|
83
|
+
@code = code
|
84
|
+
end
|
85
|
+
|
86
|
+
@description = options[:desc]
|
87
|
+
if @description.nil?
|
88
|
+
@description = Rack::Utils::HTTP_STATUS_CODES[@code]
|
89
|
+
raise "Cannot infer description from status code #{@code}" if @description.nil?
|
90
|
+
end
|
91
|
+
@scope = scope
|
92
|
+
|
93
|
+
if adapter
|
94
|
+
@response_object = adapter
|
95
|
+
else
|
96
|
+
@response_object = ResponseObject.new(method_description, scope, block)
|
97
|
+
end
|
98
|
+
|
99
|
+
@response_object.additional_properties ||= options[:additional_properties]
|
100
|
+
end
|
101
|
+
|
102
|
+
def param_description
|
103
|
+
nil
|
104
|
+
end
|
105
|
+
|
106
|
+
def params_ordered
|
107
|
+
@response_object.params_ordered
|
108
|
+
end
|
109
|
+
|
110
|
+
def additional_properties
|
111
|
+
!!@response_object.additional_properties
|
112
|
+
end
|
113
|
+
alias :allow_additional_properties :additional_properties
|
114
|
+
|
115
|
+
def to_json(lang=nil)
|
116
|
+
{
|
117
|
+
:code => code,
|
118
|
+
:description => description,
|
119
|
+
:is_array => is_array?,
|
120
|
+
:returns_object => params_ordered.map{ |param| param.to_json(lang).tap{|h| h.delete(:validations) }}.flatten,
|
121
|
+
:additional_properties => additional_properties,
|
122
|
+
}
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|