Skip to content

Commit 6bf5289

Browse files
authored
[crystal-lang] Various fixes for Crystal client (#21045)
* fix(crystal): allow users to YAML.dump(model) to ease debug * fix(crystal): make optional parameters truly optional * fix(crystal): don't send query parameters when parameter is nil * fix(crystal): implement cookie Auth * fix(crystal): fix ameba warnings * fix(crystal): update sample app specs
1 parent dcd9463 commit 6bf5289

File tree

19 files changed

+228
-117
lines changed

19 files changed

+228
-117
lines changed

modules/openapi-generator/src/main/resources/crystal/api.mustache

+7-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ module {{moduleName}}
2323
{{/required}}
2424
{{/allParams}}
2525
# @return [{{{returnType}}}{{^returnType}}nil{{/returnType}}]
26-
def {{operationId}}({{#allParams}}{{paramName}} : {{{dataType}}}{{^required}}?{{/required}}{{^-last}}, {{/-last}}{{/allParams}})
26+
def {{operationId}}({{#allParams}}{{paramName}} : {{{dataType}}}{{^required}}?{{/required}}{{^required}} = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}})
2727
{{#returnType}}data, _status_code, _headers = {{/returnType}}{{operationId}}_with_http_info({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}})
2828
{{#returnType}}data{{/returnType}}{{^returnType}}nil{{/returnType}}
2929
end
@@ -40,7 +40,7 @@ module {{moduleName}}
4040
{{/required}}
4141
{{/allParams}}
4242
# @return [Array<({{{returnType}}}{{^returnType}}nil{{/returnType}}, Integer, Hash)>] {{#returnType}}{{{.}}} data{{/returnType}}{{^returnType}}nil{{/returnType}}, response status code and response headers
43-
def {{operationId}}_with_http_info({{#allParams}}{{paramName}} : {{{dataType}}}{{^required}}?{{/required}}{{^-last}}, {{/-last}}{{/allParams}})
43+
def {{operationId}}_with_http_info({{#allParams}}{{paramName}} : {{{dataType}}}{{^required}}?{{/required}}{{^required}} = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}})
4444
if @api_client.config.debugging
4545
Log.debug {"Calling API: {{classname}}.{{operationId}} ..."}
4646
end
@@ -127,10 +127,13 @@ module {{moduleName}}
127127
# resource path
128128
local_var_path = "{{{path}}}"{{#pathParams}}.sub("{" + "{{baseName}}" + "}", URI.encode_path({{paramName}}.to_s){{^strictSpecBehavior}}.gsub("%2F", "/"){{/strictSpecBehavior}}){{/pathParams}}
129129

130+
# cookie parameters
131+
cookie_params = Hash(String, String).new
132+
130133
# query parameters
131134
query_params = Hash(String, String).new
132135
{{#queryParams}}
133-
query_params["{{{baseName}}}"] = {{#collectionFormat}}@api_client.build_collection_param({{{paramName}}}, :{{{collectionFormat}}}){{/collectionFormat}}{{^collectionFormat}}{{{paramName}}}.to_s unless {{{paramName}}}.nil?{{/collectionFormat}}
136+
query_params["{{{baseName}}}"] = {{#collectionFormat}}@api_client.build_collection_param({{{paramName}}}, :{{{collectionFormat}}}) unless {{{paramName}}}.nil?{{/collectionFormat}}{{^collectionFormat}}{{{paramName}}}.to_s unless {{{paramName}}}.nil?{{/collectionFormat}}
134137
{{/queryParams}}
135138

136139
# header parameters
@@ -170,6 +173,7 @@ module {{moduleName}}
170173
auth_names,
171174
header_params,
172175
query_params,
176+
cookie_params,
173177
form_params)
174178
if @api_client.config.debugging
175179
Log.debug {"API called: {{classname}}#{{operationId}}\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"}

modules/openapi-generator/src/main/resources/crystal/api_client.mustache

+6-5
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,15 @@ module {{moduleName}}
5050
# @param [Hash] header_params Header parameters
5151
# @param [Hash] query_params Query parameters
5252
# @param [String] auth_names Authentication scheme name
53-
def update_params_for_auth!(header_params, query_params, auth_names)
53+
def update_params_for_auth!(header_params, query_params, cookie_params, auth_names)
5454
auth_names.each do |auth_name|
5555
auth_setting = @config.auth_settings[auth_name]
5656
next unless auth_setting
5757
case auth_setting[:in]
5858
when "header" then header_params[auth_setting[:key]] = auth_setting[:value]
5959
when "query" then query_params[auth_setting[:key]] = auth_setting[:value]
60-
else raise ArgumentError.new("Authentication token must be in `query` of `header`")
60+
when "cookie" then cookie_params[auth_setting[:key]] = auth_setting[:value]
61+
else raise ArgumentError.new("Authentication token must be in `cookie`, `query` or `header`")
6162
end
6263
end
6364
end
@@ -119,7 +120,7 @@ module {{moduleName}}
119120
#
120121
# @return [Array<(Object, Integer, Hash)>] an array of 3 elements:
121122
# the data deserialized from response body (could be nil), response status code and response headers.
122-
def call_api(http_method : Symbol, path : String, operation : Symbol, return_type : String?, post_body : String?, auth_names = [] of String, header_params = {} of String => String, query_params = {} of String => String, form_params = {} of Symbol => (String | ::File))
123+
def call_api(http_method : Symbol, path : String, operation : Symbol, return_type : String?, post_body : String?, auth_names = [] of String, header_params = {} of String => String, query_params = {} of String => String, cookie_params = {} of String => String, form_params = {} of Symbol => (String | ::File))
123124
#ssl_options = {
124125
# :ca_file => @config.ssl_ca_file,
125126
# :verify => @config.ssl_verify,
@@ -128,7 +129,7 @@ module {{moduleName}}
128129
# :client_key => @config.ssl_client_key
129130
#}
130131

131-
update_params_for_auth! header_params, query_params, auth_names
132+
update_params_for_auth! header_params, query_params, cookie_params, auth_names
132133

133134
if !post_body.nil? && !post_body.empty?
134135
# use JSON string in the payload
@@ -143,7 +144,7 @@ module {{moduleName}}
143144
build_request_url(path, operation),
144145
params: query_params,
145146
headers: header_params,
146-
#cookies: cookie_params, # TODO add cookies support
147+
cookies: cookie_params,
147148
form: form_or_body,
148149
logging: @config.debugging,
149150
handle_errors: false

modules/openapi-generator/src/main/resources/crystal/model.mustache

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
require "big"
44
require "json"
5+
require "yaml"
56
require "time"
67

78
module {{moduleName}}

modules/openapi-generator/src/main/resources/crystal/partial_model_generic.mustache

+7-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
{{/description}}
44
class {{classname}}{{#parent}} < {{{.}}}{{/parent}}
55
include JSON::Serializable
6+
include YAML::Serializable
67

78
{{#hasRequired}}
89
# Required properties
@@ -269,16 +270,16 @@
269270
{{/vars}}
270271
# Checks equality by comparing each attribute.
271272
# @param [Object] Object to be compared
272-
def ==(o)
273-
return true if self.same?(o)
274-
self.class == o.class{{#vars}} &&
275-
{{name}} == o.{{name}}{{/vars}}{{#parent}} && super(o){{/parent}}
273+
def ==(other)
274+
return true if self.same?(other)
275+
self.class == other.class{{#vars}} &&
276+
{{name}} == other.{{name}}{{/vars}}{{#parent}} && super(other){{/parent}}
276277
end
277278

278279
# @see the `==` method
279280
# @param [Object] Object to be compared
280-
def eql?(o)
281-
self == o
281+
def eql?(other)
282+
self == other
282283
end
283284

284285
# Calculates hash code according to all attributes.
2.96 MB
Binary file not shown.

samples/client/petstore/crystal/spec/api_client_spec.cr

+6-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ Spectator.describe Petstore::ApiClient do
99

1010
header_params = {} of String => String
1111
query_params = {} of String => String
12+
cookie_params = {} of String => String
1213

1314
api_client = Petstore::ApiClient.new(config)
14-
api_client.update_params_for_auth!(header_params, query_params, ["petstore_auth"])
15+
api_client.update_params_for_auth!(header_params, query_params, cookie_params, ["petstore_auth"])
1516

1617
expect(header_params["Authorization"]).to eq "Bearer xxx"
1718
expect(query_params.size).to eq 0
@@ -26,9 +27,10 @@ Spectator.describe Petstore::ApiClient do
2627

2728
header_params = {} of String => String
2829
query_params = {} of String => String
30+
cookie_params = {} of String => String
2931

3032
api_client = Petstore::ApiClient.new(config)
31-
api_client.update_params_for_auth!(header_params, query_params, ["api_key"])
33+
api_client.update_params_for_auth!(header_params, query_params, cookie_params, ["api_key"])
3234

3335
expect(header_params["api_key"]).to eq "xxx"
3436
expect(query_params.empty?).to be_true
@@ -43,9 +45,10 @@ Spectator.describe Petstore::ApiClient do
4345

4446
header_params = {} of String => String
4547
query_params = {} of String => String
48+
cookie_params = {} of String => String
4649

4750
api_client = Petstore::ApiClient.new(config)
48-
api_client.update_params_for_auth!(header_params, query_params, ["api_key"])
51+
api_client.update_params_for_auth!(header_params, query_params, cookie_params, ["api_key"])
4952

5053
expect(header_params["api_key"]).to eq "Token xxx"
5154
expect(query_params.empty?).to be_true

samples/client/petstore/crystal/src/petstore/api/fake_api.cr

+4
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ module Petstore
6363
# resource path
6464
local_var_path = "/fake/parameter-name-mapping"
6565

66+
# cookie parameters
67+
cookie_params = Hash(String, String).new
68+
6669
# query parameters
6770
query_params = Hash(String, String).new
6871
query_params["type"] = _type.to_s unless _type.nil?
@@ -94,6 +97,7 @@ module Petstore
9497
auth_names,
9598
header_params,
9699
query_params,
100+
cookie_params,
97101
form_params)
98102
if @api_client.config.debugging
99103
Log.debug {"API called: FakeApi#get_parameter_name_mapping\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"}

samples/client/petstore/crystal/src/petstore/api/pet_api.cr

+40-8
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ module Petstore
4141
# resource path
4242
local_var_path = "/pet"
4343

44+
# cookie parameters
45+
cookie_params = Hash(String, String).new
46+
4447
# query parameters
4548
query_params = Hash(String, String).new
4649

@@ -71,6 +74,7 @@ module Petstore
7174
auth_names,
7275
header_params,
7376
query_params,
77+
cookie_params,
7478
form_params)
7579
if @api_client.config.debugging
7680
Log.debug {"API called: PetApi#add_pet\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"}
@@ -82,7 +86,7 @@ module Petstore
8286
#
8387
# @param pet_id [Int64] Pet id to delete
8488
# @return [nil]
85-
def delete_pet(pet_id : Int64, api_key : String?)
89+
def delete_pet(pet_id : Int64, api_key : String? = nil)
8690
delete_pet_with_http_info(pet_id, api_key)
8791
nil
8892
end
@@ -91,7 +95,7 @@ module Petstore
9195
#
9296
# @param pet_id [Int64] Pet id to delete
9397
# @return [Array<(nil, Integer, Hash)>] nil, response status code and response headers
94-
def delete_pet_with_http_info(pet_id : Int64, api_key : String?)
98+
def delete_pet_with_http_info(pet_id : Int64, api_key : String? = nil)
9599
if @api_client.config.debugging
96100
Log.debug {"Calling API: PetApi.delete_pet ..."}
97101
end
@@ -102,6 +106,9 @@ module Petstore
102106
# resource path
103107
local_var_path = "/pet/{petId}".sub("{" + "petId" + "}", URI.encode_path(pet_id.to_s).gsub("%2F", "/"))
104108

109+
# cookie parameters
110+
cookie_params = Hash(String, String).new
111+
105112
# query parameters
106113
query_params = Hash(String, String).new
107114

@@ -129,6 +136,7 @@ module Petstore
129136
auth_names,
130137
header_params,
131138
query_params,
139+
cookie_params,
132140
form_params)
133141
if @api_client.config.debugging
134142
Log.debug {"API called: PetApi#delete_pet\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"}
@@ -160,9 +168,12 @@ module Petstore
160168
# resource path
161169
local_var_path = "/pet/findByStatus"
162170

171+
# cookie parameters
172+
cookie_params = Hash(String, String).new
173+
163174
# query parameters
164175
query_params = Hash(String, String).new
165-
query_params["status"] = @api_client.build_collection_param(status, :csv)
176+
query_params["status"] = @api_client.build_collection_param(status, :csv) unless status.nil?
166177

167178
# header parameters
168179
header_params = Hash(String, String).new
@@ -189,6 +200,7 @@ module Petstore
189200
auth_names,
190201
header_params,
191202
query_params,
203+
cookie_params,
192204
form_params)
193205
if @api_client.config.debugging
194206
Log.debug {"API called: PetApi#find_pets_by_status\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"}
@@ -220,9 +232,12 @@ module Petstore
220232
# resource path
221233
local_var_path = "/pet/findByTags"
222234

235+
# cookie parameters
236+
cookie_params = Hash(String, String).new
237+
223238
# query parameters
224239
query_params = Hash(String, String).new
225-
query_params["tags"] = @api_client.build_collection_param(tags, :csv)
240+
query_params["tags"] = @api_client.build_collection_param(tags, :csv) unless tags.nil?
226241

227242
# header parameters
228243
header_params = Hash(String, String).new
@@ -249,6 +264,7 @@ module Petstore
249264
auth_names,
250265
header_params,
251266
query_params,
267+
cookie_params,
252268
form_params)
253269
if @api_client.config.debugging
254270
Log.debug {"API called: PetApi#find_pets_by_tags\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"}
@@ -280,6 +296,9 @@ module Petstore
280296
# resource path
281297
local_var_path = "/pet/{petId}".sub("{" + "petId" + "}", URI.encode_path(pet_id.to_s).gsub("%2F", "/"))
282298

299+
# cookie parameters
300+
cookie_params = Hash(String, String).new
301+
283302
# query parameters
284303
query_params = Hash(String, String).new
285304

@@ -308,6 +327,7 @@ module Petstore
308327
auth_names,
309328
header_params,
310329
query_params,
330+
cookie_params,
311331
form_params)
312332
if @api_client.config.debugging
313333
Log.debug {"API called: PetApi#get_pet_by_id\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"}
@@ -339,6 +359,9 @@ module Petstore
339359
# resource path
340360
local_var_path = "/pet"
341361

362+
# cookie parameters
363+
cookie_params = Hash(String, String).new
364+
342365
# query parameters
343366
query_params = Hash(String, String).new
344367

@@ -369,6 +392,7 @@ module Petstore
369392
auth_names,
370393
header_params,
371394
query_params,
395+
cookie_params,
372396
form_params)
373397
if @api_client.config.debugging
374398
Log.debug {"API called: PetApi#update_pet\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"}
@@ -380,7 +404,7 @@ module Petstore
380404
#
381405
# @param pet_id [Int64] ID of pet that needs to be updated
382406
# @return [nil]
383-
def update_pet_with_form(pet_id : Int64, name : String?, status : String?)
407+
def update_pet_with_form(pet_id : Int64, name : String? = nil, status : String? = nil)
384408
update_pet_with_form_with_http_info(pet_id, name, status)
385409
nil
386410
end
@@ -389,7 +413,7 @@ module Petstore
389413
#
390414
# @param pet_id [Int64] ID of pet that needs to be updated
391415
# @return [Array<(nil, Integer, Hash)>] nil, response status code and response headers
392-
def update_pet_with_form_with_http_info(pet_id : Int64, name : String?, status : String?)
416+
def update_pet_with_form_with_http_info(pet_id : Int64, name : String? = nil, status : String? = nil)
393417
if @api_client.config.debugging
394418
Log.debug {"Calling API: PetApi.update_pet_with_form ..."}
395419
end
@@ -400,6 +424,9 @@ module Petstore
400424
# resource path
401425
local_var_path = "/pet/{petId}".sub("{" + "petId" + "}", URI.encode_path(pet_id.to_s).gsub("%2F", "/"))
402426

427+
# cookie parameters
428+
cookie_params = Hash(String, String).new
429+
403430
# query parameters
404431
query_params = Hash(String, String).new
405432

@@ -430,6 +457,7 @@ module Petstore
430457
auth_names,
431458
header_params,
432459
query_params,
460+
cookie_params,
433461
form_params)
434462
if @api_client.config.debugging
435463
Log.debug {"API called: PetApi#update_pet_with_form\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"}
@@ -441,7 +469,7 @@ module Petstore
441469
#
442470
# @param pet_id [Int64] ID of pet to update
443471
# @return [ApiResponse]
444-
def upload_file(pet_id : Int64, additional_metadata : String?, file : ::File?)
472+
def upload_file(pet_id : Int64, additional_metadata : String? = nil, file : ::File? = nil)
445473
data, _status_code, _headers = upload_file_with_http_info(pet_id, additional_metadata, file)
446474
data
447475
end
@@ -450,7 +478,7 @@ module Petstore
450478
#
451479
# @param pet_id [Int64] ID of pet to update
452480
# @return [Array<(ApiResponse, Integer, Hash)>] ApiResponse data, response status code and response headers
453-
def upload_file_with_http_info(pet_id : Int64, additional_metadata : String?, file : ::File?)
481+
def upload_file_with_http_info(pet_id : Int64, additional_metadata : String? = nil, file : ::File? = nil)
454482
if @api_client.config.debugging
455483
Log.debug {"Calling API: PetApi.upload_file ..."}
456484
end
@@ -461,6 +489,9 @@ module Petstore
461489
# resource path
462490
local_var_path = "/pet/{petId}/uploadImage".sub("{" + "petId" + "}", URI.encode_path(pet_id.to_s).gsub("%2F", "/"))
463491

492+
# cookie parameters
493+
cookie_params = Hash(String, String).new
494+
464495
# query parameters
465496
query_params = Hash(String, String).new
466497

@@ -493,6 +524,7 @@ module Petstore
493524
auth_names,
494525
header_params,
495526
query_params,
527+
cookie_params,
496528
form_params)
497529
if @api_client.config.debugging
498530
Log.debug {"API called: PetApi#upload_file\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"}

0 commit comments

Comments
 (0)