Class: ChartMogul::APIResource
- Inherits:
-
Object
- Object
- Object
- ChartMogul::APIResource
show all
- Extended by:
- Forwardable
- Defined in:
- lib/chartmogul/api_resource.rb
Direct Known Subclasses
Account, Contact, Contacts, Customer, CustomerInvoices, Customers, DataSource, DataSources, Enrichment::Customers, Enrichment::DeprecatedCustomer, Invoice, Invoices, JsonImport, LineItem, Metrics::ARPAs, Metrics::ARRs, Metrics::ASPs, Metrics::Activities, Metrics::ActivitiesExport, Metrics::AllKeyMetrics, Metrics::CustomerChurnRates, Metrics::CustomerCounts, Metrics::Customers::Activities, Metrics::Customers::Subscriptions, Metrics::LTVs, Metrics::MRRChurnRates, Metrics::MRRs, Note, Notes, Opportnities, Opportunity, Ping, Plan, PlanGroup, PlanGroup::PlanGroups, PlanGroups::Plans, Plans, Subscription, SubscriptionEvent, SubscriptionEvents, Subscriptions, Task, Tasks, Transaction, Transactions::Payment, Transactions::Refund
Constant Summary
collapse
- RETRY_STATUSES =
[429, *500..599].freeze
- RETRY_EXCEPTIONS =
[
"Faraday::ConnectionFailed",
"Faraday::RetriableResponse"
].freeze
- BACKOFF_FACTOR =
2
- INTERVAL_RANDOMNESS =
0.5
- INTERVAL =
1
- MAX_INTERVAL =
60
- THREAD_CONNECTION_KEY =
"chartmogul_ruby.api_resource.connection"
Class Attribute Summary collapse
Class Method Summary
collapse
-
.build_connection ⇒ Object
-
.build_query_path(base_path, **params) ⇒ Object
Build a URL path with query parameters, handling ? vs & correctly.
-
.connection ⇒ Object
-
.custom_with_query_params!(http_method, body_data = {}, resource_key = nil) ⇒ Object
Class method version for enhanced custom! with query parameters.
-
.extract_query_params(attrs, resource_key = nil) ⇒ Object
-
.handle_other_error(exception) ⇒ Object
-
.handle_request_error(exception) ⇒ Object
-
.handling_errors ⇒ Object
-
.immutable_keys ⇒ Object
-
.json_patch(path, body) ⇒ Object
Convenience for JSON PATCH requests.
-
.json_post(path, body) ⇒ Object
Convenience for JSON POST requests.
-
.json_put(path, body) ⇒ Object
Convenience for JSON PUT requests.
-
.query_params ⇒ Object
-
.set_immutable_keys(array) ⇒ Object
When set with keys, nested hash keys of these immutable keys won't be converted to snake case.
-
.set_resource_name(name) ⇒ Object
-
.set_resource_path(path) ⇒ Object
-
.set_resource_root_key(root_key) ⇒ Object
-
.writeable_query_param(attribute, options = {}) ⇒ Object
Instance Method Summary
collapse
Class Attribute Details
.resource_name ⇒ Object
Returns the value of attribute resource_name.
23
24
25
|
# File 'lib/chartmogul/api_resource.rb', line 23
def resource_name
@resource_name
end
|
.resource_path ⇒ Object
Returns the value of attribute resource_path.
23
24
25
|
# File 'lib/chartmogul/api_resource.rb', line 23
def resource_path
@resource_path
end
|
.resource_root_key ⇒ Object
Returns the value of attribute resource_root_key.
23
24
25
|
# File 'lib/chartmogul/api_resource.rb', line 23
def resource_root_key
@resource_root_key
end
|
Class Method Details
.build_connection ⇒ Object
200
201
202
203
204
205
206
207
208
209
210
|
# File 'lib/chartmogul/api_resource.rb', line 200
def self.build_connection
Faraday.new(url: ChartMogul.api_base,
headers: { "User-Agent" => "chartmogul-ruby/#{ChartMogul::VERSION}" }) do |faraday|
faraday.use Faraday::Response::RaiseError
faraday.request :authorization, :basic, ChartMogul.api_key, ""
faraday.request :retry, max: ChartMogul.max_retries, retry_statuses: RETRY_STATUSES,
max_interval: MAX_INTERVAL, backoff_factor: BACKOFF_FACTOR,
interval_randomness: INTERVAL_RANDOMNESS, interval: INTERVAL, exceptions: RETRY_EXCEPTIONS
faraday.adapter Faraday::Adapter::NetHttp
end
end
|
.build_query_path(base_path, **params) ⇒ Object
Build a URL path with query parameters, handling ? vs & correctly
168
169
170
171
172
173
174
|
# File 'lib/chartmogul/api_resource.rb', line 168
def self.build_query_path(base_path, **params)
filtered = params.compact
return base_path if filtered.empty?
separator = base_path.include?("?") ? "&" : "?"
"#{base_path}#{separator}#{URI.encode_www_form(filtered)}"
end
|
.connection ⇒ Object
74
75
76
|
# File 'lib/chartmogul/api_resource.rb', line 74
def self.connection
Thread.current[THREAD_CONNECTION_KEY] ||= build_connection
end
|
.custom_with_query_params!(http_method, body_data = {}, resource_key = nil) ⇒ Object
Class method version for enhanced custom! with query parameters
157
158
159
160
161
162
163
164
165
|
# File 'lib/chartmogul/api_resource.rb', line 157
def self.custom_with_query_params!(http_method, body_data = {}, resource_key = nil)
attrs, query_params = (body_data, resource_key)
path_params = body_data.select { |key, _| resource_path.named_params.values.include?(key) }
path_and_query_params = path_params.merge(query_params)
path = resource_path.apply_with_get_params(path_and_query_params)
custom!(http_method, path, attrs)
end
|
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
# File 'lib/chartmogul/api_resource.rb', line 34
def self.(attrs, resource_key = nil)
remaining_attrs = attrs.dup
query_params = {}
self.query_params.each do |param|
if resource_key && remaining_attrs[resource_key].is_a?(Hash) &&
remaining_attrs[resource_key]&.key?(param) &&
remaining_attrs[resource_key][param]
query_params[param] = remaining_attrs[resource_key].delete(param)
elsif remaining_attrs.key?(param) && remaining_attrs[param]
query_params[param] = remaining_attrs.delete(param)
end
end
[remaining_attrs, query_params]
end
|
.handle_other_error(exception) ⇒ Object
114
115
116
|
# File 'lib/chartmogul/api_resource.rb', line 114
def self.handle_other_error(exception)
raise ChartMogul::ChartMogulError, exception.message
end
|
.handle_request_error(exception) ⇒ Object
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
# File 'lib/chartmogul/api_resource.rb', line 86
def self.handle_request_error(exception)
response = exception.response[:body]
http_status = exception.response[:status]
case http_status
when 400
message = "JSON schema validation hasn't passed."
raise ChartMogul::SchemaInvalidError.new(message, http_status: 400, response: response)
when 401
message = "No valid API key provided"
raise ChartMogul::UnauthorizedError.new(message, http_status: 401, response: response)
when 403
message = "The requested action is forbidden."
raise ChartMogul::ForbiddenError.new(message, http_status: 403, response: response)
when 404
message = "The requested #{resource_name} could not be found."
raise ChartMogul::NotFoundError.new(message, http_status: 404, response: response)
when 422
message = "The #{resource_name} could not be created or updated."
raise ChartMogul::ResourceInvalidError.new(message, http_status: 422, response: response)
when 500..504
message = "ChartMogul API server response error"
raise ChartMogul::ServerError.new(message, http_status: http_status, response: response)
else
message = "#{resource_name} request error has occurred."
raise ChartMogul::ChartMogulError.new(message, http_status: http_status, response: response)
end
end
|
.handling_errors ⇒ Object
78
79
80
81
82
83
84
|
# File 'lib/chartmogul/api_resource.rb', line 78
def self.handling_errors
yield
rescue Faraday::ClientError, Faraday::ServerError => e
e.response ? handle_request_error(e) : handle_other_error(e)
rescue StandardError => e
handle_other_error(e)
end
|
.immutable_keys ⇒ Object
65
66
67
|
# File 'lib/chartmogul/api_resource.rb', line 65
def self.immutable_keys
@immutable_keys ||= []
end
|
.json_patch(path, body) ⇒ Object
Convenience for JSON PATCH requests
177
178
179
180
181
182
|
# File 'lib/chartmogul/api_resource.rb', line 177
def self.json_patch(path, body)
connection.patch(path) do |req|
req.["Content-Type"] = "application/json"
req.body = JSON.dump(body)
end
end
|
.json_post(path, body) ⇒ Object
Convenience for JSON POST requests
193
194
195
196
197
198
|
# File 'lib/chartmogul/api_resource.rb', line 193
def self.json_post(path, body)
connection.post(path) do |req|
req.["Content-Type"] = "application/json"
req.body = JSON.dump(body)
end
end
|
.json_put(path, body) ⇒ Object
Convenience for JSON PUT requests
185
186
187
188
189
190
|
# File 'lib/chartmogul/api_resource.rb', line 185
def self.json_put(path, body)
connection.put(path) do |req|
req.["Content-Type"] = "application/json"
req.body = JSON.dump(body)
end
end
|
.query_params ⇒ Object
25
26
27
|
# File 'lib/chartmogul/api_resource.rb', line 25
def self.query_params
@query_params ||= Set.new
end
|
.set_immutable_keys(array) ⇒ Object
When set with keys, nested hash keys of these immutable keys won't be converted to snake case
70
71
72
|
# File 'lib/chartmogul/api_resource.rb', line 70
def self.set_immutable_keys(array)
@immutable_keys = array
end
|
.set_resource_name(name) ⇒ Object
57
58
59
|
# File 'lib/chartmogul/api_resource.rb', line 57
def self.set_resource_name(name)
@resource_name = name
end
|
.set_resource_path(path) ⇒ Object
53
54
55
|
# File 'lib/chartmogul/api_resource.rb', line 53
def self.set_resource_path(path)
@resource_path = ChartMogul::ResourcePath.new(path)
end
|
.set_resource_root_key(root_key) ⇒ Object
61
62
63
|
# File 'lib/chartmogul/api_resource.rb', line 61
def self.set_resource_root_key(root_key)
@resource_root_key = root_key
end
|
.writeable_query_param(attribute, options = {}) ⇒ Object
29
30
31
32
|
# File 'lib/chartmogul/api_resource.rb', line 29
def self.writeable_query_param(attribute, options = {})
query_params << attribute.to_sym
writeable_attr(attribute, options)
end
|
Instance Method Details
#custom_with_query_params!(http_method, body_data = {}, resource_key = nil) ⇒ Object
Enhanced custom! that automatically handles query parameters
146
147
148
149
150
151
152
153
154
|
# File 'lib/chartmogul/api_resource.rb', line 146
def custom_with_query_params!(http_method, body_data = {}, resource_key = nil)
attrs, query_params = (body_data, resource_key)
path_params = instance_attributes.select { |key, _| resource_path.named_params.values.include?(key) }
path_and_query_params = path_params.merge(query_params)
path = resource_path.apply_with_get_params(path_and_query_params)
custom!(http_method, path, attrs)
end
|
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
# File 'lib/chartmogul/api_resource.rb', line 120
def (attrs, resource_key = nil)
remaining_attrs = attrs.dup
query_params = {}
self.class.query_params.each do |param|
if resource_key && remaining_attrs[resource_key].is_a?(Hash) &&
remaining_attrs[resource_key]&.key?(param) &&
remaining_attrs[resource_key][param]
query_params[param] = remaining_attrs[resource_key].delete(param)
elsif remaining_attrs.key?(param) && remaining_attrs[param]
query_params[param] = remaining_attrs.delete(param)
end
end
[remaining_attrs, query_params]
end
|
#path_with_query_params(attrs) ⇒ Object
Generate path with query parameters applied
140
141
142
143
|
# File 'lib/chartmogul/api_resource.rb', line 140
def path_with_query_params(attrs)
_, query_params = (attrs)
query_params.empty? ? resource_path.path : resource_path.apply_with_get_params(query_params)
end
|