Deserialize response for "object" type in Ruby client

This commit is contained in:
xhh 2015-06-12 20:15:48 +08:00
parent 672fcd5a14
commit e38fc2c3da
4 changed files with 78 additions and 29 deletions

View File

@ -48,12 +48,21 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
languageSpecificPrimitives.add("string");
languageSpecificPrimitives.add("DateTime");
typeMapping.put("long", "int");
typeMapping.put("integer", "int");
typeMapping.put("Array", "array");
typeMapping.put("String", "string");
typeMapping.put("List", "array");
typeMapping.put("map", "map");
typeMapping.put("string", "String");
typeMapping.put("char", "String");
typeMapping.put("int", "Integer");
typeMapping.put("integer", "Integer");
typeMapping.put("long", "Integer");
typeMapping.put("short", "Integer");
typeMapping.put("float", "Float");
typeMapping.put("double", "Float");
typeMapping.put("number", "Float");
typeMapping.put("DateTime", "DateTime");
typeMapping.put("boolean", "BOOLEAN");
typeMapping.put("array", "Array");
typeMapping.put("List", "Array");
typeMapping.put("map", "Hash");
typeMapping.put("object", "Hash");
String baseFolder = "lib" + File.separatorChar + gemName;
String swaggerFolder = baseFolder + File.separatorChar + "swagger";
@ -107,11 +116,11 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
Property inner = ap.getItems();
return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]";
return getSwaggerType(p) + "<" + getTypeDeclaration(inner) + ">";
} else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
return getSwaggerType(p) + "[string," + getTypeDeclaration(inner) + "]";
return getSwaggerType(p) + "<String, " + getTypeDeclaration(inner) + ">";
}
return super.getTypeDeclaration(p);
}

View File

@ -51,8 +51,8 @@ module {{moduleName}}
{{/bodyParam}}
auth_names = [{{#authMethods}}'{{name}}'{{#hasMore}}, {{/hasMore}}{{/authMethods}}]
{{#returnType}}response = Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body
{{#returnContainer}}response.map {|response| {{/returnContainer}}obj = {{returnBaseType}}.new() and obj.build_from_hash(response){{#returnContainer}} }{{/returnContainer}}{{/returnType}}{{^returnType}}Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make
{{#returnType}}response = Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make
response.deserialize('{{{returnType}}}'){{/returnType}}{{^returnType}}Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make
nil{{/returnType}}
end
{{/operation}}

View File

@ -15,7 +15,7 @@ module {{moduleName}}
def build_from_hash(attributes)
return nil unless attributes.is_a?(Hash)
self.class.swagger_types.each_pair do |key, type|
if type =~ /^array\[(.*)\]/i
if type =~ /^Array<(.*)>/i
if attributes[self.class.attribute_map[key]].is_a?(Array)
self.send("#{key}=", attributes[self.class.attribute_map[key]].map{ |v| _deserialize($1, v) } )
else
@ -35,13 +35,13 @@ module {{moduleName}}
case type.to_sym
when :DateTime
DateTime.parse(value)
when :string
when :String
value.to_s
when :int
when :Integer
value.to_i
when :double
when :Float
value.to_f
when :boolean
when :BOOLEAN
if value =~ /^(true|t|yes|y|1)$/i
true
else

View File

@ -2,6 +2,7 @@ module {{moduleName}}
module Swagger
class Response
require 'json'
require 'date'
attr_accessor :raw
@ -9,8 +10,8 @@ module {{moduleName}}
self.raw = raw
case self.code
when 500..510 then raise(ServerError, self.error_message)
when 299..426 then raise(ClientError, self.error_message)
when 500..510 then raise(ServerError, self.body)
when 299..426 then raise(ClientError, self.body)
end
end
@ -18,19 +19,58 @@ module {{moduleName}}
raw.code
end
# Account for error messages that take different forms...
def error_message
body['message']
rescue
body
def body
raw.body
end
# If body is JSON, parse it
# Otherwise return raw string
def body
JSON.parse(raw.body, :symbolize_names => true)
rescue
raw.body
# Deserialize the raw response body to the given return type.
#
# @param [String] return_type some examples: "User", "Array[User]", "Hash[String,Integer]"
def deserialize(return_type)
return nil if body.blank?
# ensuring a default content type
content_type = raw.headers_hash['Content-Type'] || 'application/json'
unless content_type.start_with?('application/json')
fail "Content-Type is not supported: #{content_type}"
end
begin
data = JSON.parse(body, :symbolize_names => true)
rescue JSON::ParserError => e
if return_type == 'String'
return body
else
raise e
end
end
build_models data, return_type
end
# Build model(s) from Hash data for array/hash values of the response.
def build_models(data, return_type)
case return_type
when /\AArray<(.+)>\z/
sub_type = $1
data.map {|item| build_models(item, sub_type) }
when /\AHash\<String, (.+)\>\z/
sub_type = $1
{}.tap do |hash|
data.each {|k, v| hash[k] = build_models(v, sub_type) }
end
when 'String', 'Integer', 'Float', 'BOOLEAN'
# primitives, return directly
data
when 'DateTime'
DateTime.parse data
else
# models
{{moduleName}}.const_get(return_type).new.tap do |model|
model.build_from_hash data
end
end
end
# `headers_hash` is a Typhoeus-specific extension of Hash,
@ -58,7 +98,7 @@ module {{moduleName}}
def pretty_body
return unless body.present?
case format
when 'json' then JSON.pretty_generate(body).gsub(/\n/, '<br/>')
when 'json' then JSON.pretty_generate(JSON.parse(body)).gsub(/\n/, '<br/>')
end
end