apipie-rails 0.5.7 → 0.5.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|