lib/apipie/response_description.rb
module Apipie
class ResponseDescription
class ResponseObject
include Apipie::DSL::Base
include Apipie::DSL::Param
attr_accessor :additional_properties, :typename
attr_reader :headers
def initialize(method_description, scope, block, typename)
@method_description = method_description
@scope = scope
@param_group = {scope: scope}
@additional_properties = false
@typename = typename
@headers = []
self.instance_exec(&block) if block
prepare_hash_params
end
# this routine overrides Param#_default_param_group_scope and is called if Param#param_group is
# invoked during the instance_exec call in ResponseObject#initialize
def _default_param_group_scope
@scope
end
def name
"response #{@code} for #{@method_description.method}"
end
def params_ordered
@params_ordered ||= _apipie_dsl_data[:params].map do |args|
options = args.find { |arg| arg.is_a? Hash }
options[:param_group] = @param_group
Apipie::ParamDescription.from_dsl_data(@method_description, args) unless options[:only_in] == :request
end.compact
end
def prepare_hash_params
@hash_params = params_ordered.reduce({}) do |h, param|
h.update(param.name.to_sym => param)
end
end
# @param [String] header_name
# @param [String, symbol, Class] validator
# @param [String] description
# @param [Hash] options
def header(header_name, validator, description, options = {})
@headers << {
name: header_name,
validator: validator.to_s.downcase,
description: description,
options: options
}
end
end
end
class ResponseDescription
include Apipie::DSL::Base
include Apipie::DSL::Param
attr_reader :code, :description, :scope, :type_ref, :hash_validator, :is_array_of
def self.from_dsl_data(method_description, code, args)
options, scope, block, adapter = args
Apipie::ResponseDescription.new(method_description,
code,
options,
scope,
block,
adapter)
end
def initialize(method_description, code, options, scope, block, adapter)
@type_ref = options[:param_group]
@is_array_of = options[:array_of] || false
raise ReturnsMultipleDefinitionError, options if @is_array_of && @type_ref
@type_ref ||= @is_array_of
@method_description = method_description
@code =
if code.is_a? Symbol
begin
Rack::Utils.status_code(code)
rescue ArgumentError
nil
end
else
code
end
@description = options[:desc]
if @description.nil?
@description = Rack::Utils::HTTP_STATUS_CODES[@code]
raise "Cannot infer description from status code #{@code}" if @description.nil?
end
@scope = scope
if adapter
@response_object = adapter
else
@response_object = ResponseObject.new(method_description, scope, block, @type_ref)
end
@response_object.additional_properties ||= options[:additional_properties]
end
def is_array?
@is_array_of != false
end
def typename
@response_object.typename
end
def param_description
nil
end
def params_ordered
@response_object.params_ordered
end
def additional_properties
!!@response_object.additional_properties
end
alias allow_additional_properties additional_properties
# @return [Array<Hash>]
def headers
# TODO: Support headers for Apipie::ResponseDescriptionAdapter
if @response_object.is_a?(Apipie::ResponseDescriptionAdapter)
return []
end
@response_object.headers
end
# @return [Hash{Symbol->TrueClass | FalseClass}]
def to_json(lang = nil)
{
:code => code,
:description => Apipie.app.translate(description, lang),
:is_array => is_array?,
:returns_object => params_ordered.map{ |param| param.to_json(lang).tap{|h| h.delete(:validations) }}.flatten,
:additional_properties => additional_properties,
:headers => headers
}
end
end
end