Skip to content

Commit e12100b

Browse files
[Ruby] Add support for faraday 2.x (#12112)
* [ruby] Add faraday 2.x support * Remove redundant params_encoder config * Memoize Faraday connection and refactor
1 parent a60df64 commit e12100b

File tree

5 files changed

+120
-68
lines changed

5 files changed

+120
-68
lines changed

modules/openapi-generator/src/main/resources/ruby-client/api_client.mustache

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ require 'typhoeus'
1212
{{/isFaraday}}
1313
{{#isFaraday}}
1414
require 'faraday'
15+
require 'faraday/multipart' if Gem::Version.new(Faraday::VERSION) >= Gem::Version.new('2.0')
1516
{{/isFaraday}}
1617

1718
module {{moduleName}}

modules/openapi-generator/src/main/resources/ruby-client/api_client_faraday_partial.mustache

Lines changed: 57 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,24 @@
33
# @return [Array<(Object, Integer, Hash)>] an array of 3 elements:
44
# the data deserialized from response body (could be nil), response status code and response headers.
55
def call_api(http_method, path, opts = {})
6-
ssl_options = {
7-
:ca_file => @config.ssl_ca_file,
8-
:verify => @config.ssl_verify,
9-
:verify_mode => @config.ssl_verify_mode,
10-
:client_cert => @config.ssl_client_cert,
11-
:client_key => @config.ssl_client_key
12-
}
13-
request_options = {
14-
:params_encoder => @config.params_encoder
15-
}
16-
connection = Faraday.new(:url => config.base_url, :ssl => ssl_options, :request => request_options) do |conn|
17-
conn.request(:basic_auth, config.username, config.password)
18-
@config.configure_middleware(conn)
19-
if opts[:header_params]["Content-Type"] == "multipart/form-data"
20-
conn.request :multipart
21-
conn.request :url_encoded
22-
end
23-
conn.adapter(Faraday.default_adapter)
24-
end
25-
266
begin
27-
response = connection.public_send(http_method.to_sym.downcase) do |req|
7+
response = connection(opts).public_send(http_method.to_sym.downcase) do |req|
288
build_request(http_method, path, req, opts)
299
end
3010

31-
if @config.debugging
32-
@config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n"
11+
if config.debugging
12+
config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n"
3313
end
3414

3515
unless response.success?
3616
if response.status == 0
3717
# Errors from libcurl will be made visible here
38-
fail ApiError.new(:code => 0,
39-
:message => response.return_message)
18+
fail ApiError.new(code: 0,
19+
message: response.return_message)
4020
else
41-
fail ApiError.new(:code => response.status,
42-
:response_headers => response.headers,
43-
:response_body => response.body),
21+
fail ApiError.new(code: response.status,
22+
response_headers: response.headers,
23+
response_body: response.body),
4424
response.reason_phrase
4525
end
4626
end
@@ -77,17 +57,17 @@
7757

7858
if [:post, :patch, :put, :delete].include?(http_method)
7959
req_body = build_request_body(header_params, form_params, opts[:body])
80-
if @config.debugging
81-
@config.logger.debug "HTTP request body param ~BEGIN~\n#{req_body}\n~END~\n"
60+
if config.debugging
61+
config.logger.debug "HTTP request body param ~BEGIN~\n#{req_body}\n~END~\n"
8262
end
8363
end
8464
request.headers = header_params
8565
request.body = req_body
8666

8767
# Overload default options only if provided
88-
request.options.params_encoder = @config.params_encoder if @config.params_encoder
89-
request.options.timeout = @config.timeout if @config.timeout
90-
request.options.verbose = @config.debugging if @config.debugging
68+
request.options.params_encoder = config.params_encoder if config.params_encoder
69+
request.options.timeout = config.timeout if config.timeout
70+
request.options.verbose = config.debugging if config.debugging
9171

9272
request.url url
9373
request.params = query_params
@@ -135,3 +115,47 @@
135115
@stream << chunk
136116
end
137117
end
118+
119+
def connection(opts)
120+
opts[:header_params]['Content-Type'] == 'multipart/form-data' ? connection_multipart : connection_regular
121+
end
122+
123+
def connection_multipart
124+
@connection_multipart ||= build_connection do |conn|
125+
conn.request :multipart
126+
conn.request :url_encoded
127+
end
128+
end
129+
130+
def connection_regular
131+
@connection_regular ||= build_connection
132+
end
133+
134+
def build_connection
135+
Faraday.new(url: config.base_url, ssl: ssl_options) do |conn|
136+
basic_auth(conn)
137+
config.configure_middleware(conn)
138+
yield(conn) if block_given?
139+
conn.adapter(Faraday.default_adapter)
140+
end
141+
end
142+
143+
def ssl_options
144+
{
145+
ca_file: config.ssl_ca_file,
146+
verify: config.ssl_verify,
147+
verify_mode: config.ssl_verify_mode,
148+
client_cert: config.ssl_client_cert,
149+
client_key: config.ssl_client_key
150+
}
151+
end
152+
153+
def basic_auth(conn)
154+
if config.username && config.password
155+
if Gem::Version.new(Faraday::VERSION) >= Gem::Version.new('2.0')
156+
conn.request(:authorization, :basic, config.username, config.password)
157+
else
158+
conn.request(:basic_auth, config.username, config.password)
159+
end
160+
end
161+
end

modules/openapi-generator/src/main/resources/ruby-client/gemspec.mustache

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ Gem::Specification.new do |s|
2020
s.required_ruby_version = "{{{gemRequiredRubyVersion}}}{{^gemRequiredRubyVersion}}>= 2.4{{/gemRequiredRubyVersion}}"
2121

2222
{{#isFaraday}}
23-
s.add_runtime_dependency 'faraday', '~> 1.0', '>= 1.0.1'
23+
s.add_runtime_dependency 'faraday', '>= 1.0.1', '< 3.0'
24+
s.add_runtime_dependency 'faraday-multipart'
2425
{{/isFaraday}}
2526
{{^isFaraday}}
2627
s.add_runtime_dependency 'typhoeus', '~> 1.0', '>= 1.0.1'

samples/client/petstore/ruby-faraday/lib/petstore/api_client.rb

Lines changed: 58 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
require 'tempfile'
1717
require 'time'
1818
require 'faraday'
19+
require 'faraday/multipart' if Gem::Version.new(Faraday::VERSION) >= Gem::Version.new('2.0')
1920

2021
module Petstore
2122
class ApiClient
@@ -47,44 +48,24 @@ def self.default
4748
# @return [Array<(Object, Integer, Hash)>] an array of 3 elements:
4849
# the data deserialized from response body (could be nil), response status code and response headers.
4950
def call_api(http_method, path, opts = {})
50-
ssl_options = {
51-
:ca_file => @config.ssl_ca_file,
52-
:verify => @config.ssl_verify,
53-
:verify_mode => @config.ssl_verify_mode,
54-
:client_cert => @config.ssl_client_cert,
55-
:client_key => @config.ssl_client_key
56-
}
57-
request_options = {
58-
:params_encoder => @config.params_encoder
59-
}
60-
connection = Faraday.new(:url => config.base_url, :ssl => ssl_options, :request => request_options) do |conn|
61-
conn.request(:basic_auth, config.username, config.password)
62-
@config.configure_middleware(conn)
63-
if opts[:header_params]["Content-Type"] == "multipart/form-data"
64-
conn.request :multipart
65-
conn.request :url_encoded
66-
end
67-
conn.adapter(Faraday.default_adapter)
68-
end
69-
7051
begin
71-
response = connection.public_send(http_method.to_sym.downcase) do |req|
52+
response = connection(opts).public_send(http_method.to_sym.downcase) do |req|
7253
build_request(http_method, path, req, opts)
7354
end
7455

75-
if @config.debugging
76-
@config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n"
56+
if config.debugging
57+
config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n"
7758
end
7859

7960
unless response.success?
8061
if response.status == 0
8162
# Errors from libcurl will be made visible here
82-
fail ApiError.new(:code => 0,
83-
:message => response.return_message)
63+
fail ApiError.new(code: 0,
64+
message: response.return_message)
8465
else
85-
fail ApiError.new(:code => response.status,
86-
:response_headers => response.headers,
87-
:response_body => response.body),
66+
fail ApiError.new(code: response.status,
67+
response_headers: response.headers,
68+
response_body: response.body),
8869
response.reason_phrase
8970
end
9071
end
@@ -121,17 +102,17 @@ def build_request(http_method, path, request, opts = {})
121102

122103
if [:post, :patch, :put, :delete].include?(http_method)
123104
req_body = build_request_body(header_params, form_params, opts[:body])
124-
if @config.debugging
125-
@config.logger.debug "HTTP request body param ~BEGIN~\n#{req_body}\n~END~\n"
105+
if config.debugging
106+
config.logger.debug "HTTP request body param ~BEGIN~\n#{req_body}\n~END~\n"
126107
end
127108
end
128109
request.headers = header_params
129110
request.body = req_body
130111

131112
# Overload default options only if provided
132-
request.options.params_encoder = @config.params_encoder if @config.params_encoder
133-
request.options.timeout = @config.timeout if @config.timeout
134-
request.options.verbose = @config.debugging if @config.debugging
113+
request.options.params_encoder = config.params_encoder if config.params_encoder
114+
request.options.timeout = config.timeout if config.timeout
115+
request.options.verbose = config.debugging if config.debugging
135116

136117
request.url url
137118
request.params = query_params
@@ -180,6 +161,50 @@ def download_file(request)
180161
end
181162
end
182163

164+
def connection(opts)
165+
opts[:header_params]['Content-Type'] == 'multipart/form-data' ? connection_multipart : connection_regular
166+
end
167+
168+
def connection_multipart
169+
@connection_multipart ||= build_connection do |conn|
170+
conn.request :multipart
171+
conn.request :url_encoded
172+
end
173+
end
174+
175+
def connection_regular
176+
@connection_regular ||= build_connection
177+
end
178+
179+
def build_connection
180+
Faraday.new(url: config.base_url, ssl: ssl_options) do |conn|
181+
basic_auth(conn)
182+
config.configure_middleware(conn)
183+
yield(conn) if block_given?
184+
conn.adapter(Faraday.default_adapter)
185+
end
186+
end
187+
188+
def ssl_options
189+
{
190+
ca_file: config.ssl_ca_file,
191+
verify: config.ssl_verify,
192+
verify_mode: config.ssl_verify_mode,
193+
client_cert: config.ssl_client_cert,
194+
client_key: config.ssl_client_key
195+
}
196+
end
197+
198+
def basic_auth(conn)
199+
if config.username && config.password
200+
if Gem::Version.new(Faraday::VERSION) >= Gem::Version.new('2.0')
201+
conn.request(:authorization, :basic, config.username, config.password)
202+
else
203+
conn.request(:basic_auth, config.username, config.password)
204+
end
205+
end
206+
end
207+
183208
# Check if the given MIME is a JSON MIME.
184209
# JSON MIME examples:
185210
# application/json

samples/client/petstore/ruby-faraday/petstore.gemspec

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ Gem::Specification.new do |s|
2727
s.license = "Unlicense"
2828
s.required_ruby_version = ">= 2.4"
2929

30-
s.add_runtime_dependency 'faraday', '~> 1.0', '>= 1.0.1'
30+
s.add_runtime_dependency 'faraday', '>= 1.0.1', '< 3.0'
31+
s.add_runtime_dependency 'faraday-multipart'
3132

3233
s.add_development_dependency 'rspec', '~> 3.6', '>= 3.6.0'
3334

0 commit comments

Comments
 (0)