-
-
Notifications
You must be signed in to change notification settings - Fork 167
/
api_request.rb
200 lines (160 loc) · 5.19 KB
/
api_request.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
module Gibbon
class APIRequest
include Helpers
def initialize(builder: nil)
@request_builder = builder
end
def post(params: nil, headers: nil, body: nil)
validate_api_key
begin
response = self.rest_client.post do |request|
configure_request(request: request, params: params, headers: headers, body: MultiJson.dump(body))
end
parse_response(response)
rescue => e
handle_error(e)
end
end
def patch(params: nil, headers: nil, body: nil)
validate_api_key
begin
response = self.rest_client.patch do |request|
configure_request(request: request, params: params, headers: headers, body: MultiJson.dump(body))
end
parse_response(response)
rescue => e
handle_error(e)
end
end
def put(params: nil, headers: nil, body: nil)
validate_api_key
begin
response = self.rest_client.put do |request|
configure_request(request: request, params: params, headers: headers, body: MultiJson.dump(body))
end
parse_response(response)
rescue => e
handle_error(e)
end
end
def get(params: nil, headers: nil)
validate_api_key
begin
response = self.rest_client.get do |request|
configure_request(request: request, params: params, headers: headers)
end
parse_response(response)
rescue => e
handle_error(e)
end
end
def delete(params: nil, headers: nil)
validate_api_key
begin
response = self.rest_client.delete do |request|
configure_request(request: request, params: params, headers: headers)
end
parse_response(response)
rescue => e
handle_error(e)
end
end
protected
# Convenience accessors
def api_key
@request_builder.api_key
end
def api_endpoint
@request_builder.api_endpoint
end
def timeout
@request_builder.timeout
end
def open_timeout
@request_builder.open_timeout
end
def proxy
@request_builder.proxy
end
def adapter
@request_builder.faraday_adapter
end
def symbolize_keys
@request_builder.symbolize_keys
end
# Helpers
def handle_error(error)
error_params = {}
begin
if (error.is_a?(Faraday::ClientError) || error.is_a?(Faraday::ServerError)) && error.response
error_params[:status_code] = error.response[:status]
error_params[:raw_body] = error.response[:body]
parsed_response = MultiJson.load(error.response[:body], symbolize_keys: symbolize_keys)
if parsed_response
error_params[:body] = parsed_response
title_key = symbolize_keys ? :title : "title"
detail_key = symbolize_keys ? :detail : "detail"
error_params[:title] = parsed_response[title_key] if parsed_response[title_key]
error_params[:detail] = parsed_response[detail_key] if parsed_response[detail_key]
end
end
rescue MultiJson::ParseError
end
error_to_raise = MailChimpError.new(error.message, error_params)
raise error_to_raise
end
def configure_request(request: nil, params: nil, headers: nil, body: nil)
if request
request.params.merge!(params) if params
request.headers['Content-Type'] = 'application/json'
request.headers.merge!(headers) if headers
request.body = body if body
request.options.timeout = self.timeout
request.options.open_timeout = self.open_timeout
end
end
def rest_client
client = Faraday.new(self.api_url, proxy: self.proxy, ssl: { version: "TLSv1_2" }) do |faraday|
faraday.response :raise_error
faraday.adapter adapter
if @request_builder.debug
faraday.response :logger, @request_builder.logger, bodies: true
end
if Faraday::VERSION.to_i >= 2
faraday.request :authorization, :basic, 'apikey', self.api_key
else
faraday.request :basic_auth, 'apikey', self.api_key
end
end
client
end
def parse_response(response)
parsed_response = nil
if response.body && !response.body.empty?
begin
headers = response.headers
body = MultiJson.load(response.body, symbolize_keys: symbolize_keys)
parsed_response = Response.new(headers: headers, body: body)
rescue MultiJson::ParseError
error_params = { title: "UNPARSEABLE_RESPONSE", status_code: 500 }
error = MailChimpError.new("Unparseable response: #{response.body}", error_params)
raise error
end
end
parsed_response
end
def validate_api_key
api_key = self.api_key
unless api_key && (api_key["-"] || self.api_endpoint)
raise Gibbon::GibbonError, "You must set an api_key prior to making a call"
end
end
def api_url
base_api_url + @request_builder.path
end
def base_api_url
computed_api_endpoint = "https://#{get_data_center_from_api_key(self.api_key)}api.mailchimp.com"
"#{self.api_endpoint || computed_api_endpoint}/3.0/"
end
end
end