From 76eeb51af628c301444007382c1269d440f0ee8a Mon Sep 17 00:00:00 2001 From: xhh Date: Thu, 5 Nov 2015 20:02:09 +0800 Subject: [PATCH] Support collectionFormat in Ruby client for header, query and form parameters --- .../io/swagger/codegen/DefaultCodegen.java | 3 ++ .../src/main/resources/ruby/api.mustache | 12 +++---- .../main/resources/ruby/api_client.mustache | 32 +++++++++++++++++-- samples/client/petstore/ruby/lib/petstore.rb | 2 +- .../petstore/ruby/lib/petstore/api/pet_api.rb | 6 ++-- .../petstore/ruby/lib/petstore/api_client.rb | 32 +++++++++++++++++-- .../petstore/ruby/spec/api_client_spec.rb | 29 +++++++++++++++++ 7 files changed, 100 insertions(+), 16 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java index 675091da120..b5a6f88f14d 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java @@ -1446,6 +1446,9 @@ public class DefaultCodegen { } property = new ArrayProperty(inner); collectionFormat = qp.getCollectionFormat(); + if (collectionFormat == null) { + collectionFormat = "csv"; + } CodegenProperty pr = fromProperty("inner", inner); p.baseType = pr.datatype; p.isContainer = true; diff --git a/modules/swagger-codegen/src/main/resources/ruby/api.mustache b/modules/swagger-codegen/src/main/resources/ruby/api.mustache index ad885dac94e..a43260c0607 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/api.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/api.mustache @@ -36,8 +36,8 @@ module {{moduleName}} # query parameters query_params = {}{{#queryParams}}{{#required}} - query_params[:'{{{baseName}}}'] = {{{paramName}}}{{/required}}{{/queryParams}}{{#queryParams}}{{^required}} - query_params[:'{{{baseName}}}'] = opts[:'{{{paramName}}}'] if opts[:'{{{paramName}}}']{{/required}}{{/queryParams}} + query_params[:'{{{baseName}}}'] = {{#collectionFormat}}@api_client.build_collection_param({{{paramName}}}, :{{{collectionFormat}}}){{/collectionFormat}}{{^collectionFormat}}{{{paramName}}}{{/collectionFormat}}{{/required}}{{/queryParams}}{{#queryParams}}{{^required}} + query_params[:'{{{baseName}}}'] = {{#collectionFormat}}@api_client.build_collection_param(opts[:'{{{paramName}}}'], :{{{collectionFormat}}}){{/collectionFormat}}{{^collectionFormat}}opts[:'{{{paramName}}}']{{/collectionFormat}} if opts[:'{{{paramName}}}']{{/required}}{{/queryParams}} # header parameters header_params = {} @@ -49,13 +49,13 @@ module {{moduleName}} # HTTP header 'Content-Type' _header_content_type = [{{#consumes}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/consumes}}] header_params['Content-Type'] = @api_client.select_header_content_type(_header_content_type){{#headerParams}}{{#required}} - header_params[:'{{{baseName}}}'] = {{{paramName}}}{{/required}}{{/headerParams}}{{#headerParams}}{{^required}} - header_params[:'{{{baseName}}}'] = opts[:'{{{paramName}}}'] if opts[:'{{{paramName}}}']{{/required}}{{/headerParams}} + header_params[:'{{{baseName}}}'] = {{#collectionFormat}}@api_client.build_collection_param({{{paramName}}}, :{{{collectionFormat}}}){{/collectionFormat}}{{^collectionFormat}}{{{paramName}}}{{/collectionFormat}}{{/required}}{{/headerParams}}{{#headerParams}}{{^required}} + header_params[:'{{{baseName}}}'] = {{#collectionFormat}}@api_client.build_collection_param(opts[:'{{{paramName}}}'], :{{{collectionFormat}}}){{/collectionFormat}}{{^collectionFormat}}opts[:'{{{paramName}}}']{{/collectionFormat}} if opts[:'{{{paramName}}}']{{/required}}{{/headerParams}} # form parameters form_params = {}{{#formParams}}{{#required}} - form_params["{{baseName}}"] = {{paramName}}{{/required}}{{/formParams}}{{#formParams}}{{^required}} - form_params["{{baseName}}"] = opts[:'{{paramName}}'] if opts[:'{{paramName}}']{{/required}}{{/formParams}} + form_params["{{baseName}}"] = {{#collectionFormat}}@api_client.build_collection_param({{{paramName}}}, :{{{collectionFormat}}}){{/collectionFormat}}{{^collectionFormat}}{{{paramName}}}{{/collectionFormat}}{{/required}}{{/formParams}}{{#formParams}}{{^required}} + form_params["{{baseName}}"] = {{#collectionFormat}}@api_client.build_collection_param(opts[:'{{{paramName}}}'], :{{{collectionFormat}}}){{/collectionFormat}}{{^collectionFormat}}opts[:'{{{paramName}}}']{{/collectionFormat}} if opts[:'{{paramName}}']{{/required}}{{/formParams}} # http body (model) {{^bodyParam}}post_body = nil diff --git a/modules/swagger-codegen/src/main/resources/ruby/api_client.mustache b/modules/swagger-codegen/src/main/resources/ruby/api_client.mustache index 2bdcf6dc7be..4ef665bddf2 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/api_client.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/api_client.mustache @@ -189,9 +189,15 @@ module {{moduleName}} # http form if header_params['Content-Type'] == 'application/x-www-form-urlencoded' || header_params['Content-Type'] == 'multipart/form-data' - data = form_params.dup - data.each do |key, value| - data[key] = value.to_s if value && !value.is_a?(File) + data = {} + form_params.each do |key, value| + case value + when File, Array, nil + # let typhoeus handle File, Array and nil parameters + data[key] = value + else + data[key] = value.to_s + end end elsif body data = body.is_a?(String) ? body : body.to_json @@ -269,5 +275,25 @@ module {{moduleName}} obj end end + + # Build parameter value according to the given collection format. + # @param [String] collection_format one of :csv, :ssv, :tsv, :pipes and :multi + def build_collection_param(param, collection_format) + case collection_format + when :csv + param.join(',') + when :ssv + param.join(' ') + when :tsv + param.join("\t") + when :pipes + param.join('|') + when :multi + # return the array directly as typhoeus will handle it as expected + param + else + fail "unknown collection format: #{collection_format.inspect}" + end + end end end diff --git a/samples/client/petstore/ruby/lib/petstore.rb b/samples/client/petstore/ruby/lib/petstore.rb index 61640d687ac..c13e99f29fc 100644 --- a/samples/client/petstore/ruby/lib/petstore.rb +++ b/samples/client/petstore/ruby/lib/petstore.rb @@ -14,8 +14,8 @@ require 'petstore/models/order' # APIs require 'petstore/api/user_api' -require 'petstore/api/pet_api' require 'petstore/api/store_api' +require 'petstore/api/pet_api' module Petstore class << self diff --git a/samples/client/petstore/ruby/lib/petstore/api/pet_api.rb b/samples/client/petstore/ruby/lib/petstore/api/pet_api.rb index 4b956aeadcc..887f86dd45c 100644 --- a/samples/client/petstore/ruby/lib/petstore/api/pet_api.rb +++ b/samples/client/petstore/ruby/lib/petstore/api/pet_api.rb @@ -117,7 +117,7 @@ module Petstore # query parameters query_params = {} - query_params[:'status'] = opts[:'status'] if opts[:'status'] + query_params[:'status'] = @api_client.build_collection_param(opts[:'status'], :multi) if opts[:'status'] # header parameters header_params = {} @@ -166,7 +166,7 @@ module Petstore # query parameters query_params = {} - query_params[:'tags'] = opts[:'tags'] if opts[:'tags'] + query_params[:'tags'] = @api_client.build_collection_param(opts[:'tags'], :multi) if opts[:'tags'] # header parameters header_params = {} @@ -237,7 +237,7 @@ module Petstore post_body = nil - auth_names = ['api_key', 'petstore_auth'] + auth_names = ['api_key'] result = @api_client.call_api(:GET, path, :header_params => header_params, :query_params => query_params, diff --git a/samples/client/petstore/ruby/lib/petstore/api_client.rb b/samples/client/petstore/ruby/lib/petstore/api_client.rb index 4f747bcd6a1..92a61bac4a6 100644 --- a/samples/client/petstore/ruby/lib/petstore/api_client.rb +++ b/samples/client/petstore/ruby/lib/petstore/api_client.rb @@ -189,9 +189,15 @@ module Petstore # http form if header_params['Content-Type'] == 'application/x-www-form-urlencoded' || header_params['Content-Type'] == 'multipart/form-data' - data = form_params.dup - data.each do |key, value| - data[key] = value.to_s if value && !value.is_a?(File) + data = {} + form_params.each do |key, value| + case value + when File, Array, nil + # let typhoeus handle File, Array and nil parameters + data[key] = value + else + data[key] = value.to_s + end end elsif body data = body.is_a?(String) ? body : body.to_json @@ -269,5 +275,25 @@ module Petstore obj end end + + # Build parameter value according to the given collection format. + # @param [String] collection_format one of :csv, :ssv, :tsv, :pipes and :multi + def build_collection_param(param, collection_format) + case collection_format + when :csv + param.join(',') + when :ssv + param.join(' ') + when :tsv + param.join("\t") + when :pipes + param.join('|') + when :multi + # return the array directly as typhoeus will handle it as expected + param + else + fail "unknown collection format: #{collection_format.inspect}" + end + end end end diff --git a/samples/client/petstore/ruby/spec/api_client_spec.rb b/samples/client/petstore/ruby/spec/api_client_spec.rb index cd9016c9a0b..eeb27300bf3 100644 --- a/samples/client/petstore/ruby/spec/api_client_spec.rb +++ b/samples/client/petstore/ruby/spec/api_client_spec.rb @@ -116,4 +116,33 @@ describe Petstore::ApiClient do end end + describe "#build_collection_param" do + let(:param) { ['aa', 'bb', 'cc'] } + let(:api_client) { Petstore::ApiClient.new } + + it "works for csv" do + api_client.build_collection_param(param, :csv).should == 'aa,bb,cc' + end + + it "works for ssv" do + api_client.build_collection_param(param, :ssv).should == 'aa bb cc' + end + + it "works for tsv" do + api_client.build_collection_param(param, :tsv).should == "aa\tbb\tcc" + end + + it "works for pipes" do + api_client.build_collection_param(param, :pipes).should == 'aa|bb|cc' + end + + it "works for multi" do + api_client.build_collection_param(param, :multi).should == ['aa', 'bb', 'cc'] + end + + it "fails for invalid collection format" do + proc { api_client.build_collection_param(param, :INVALID) }.should raise_error + end + end + end