patient_http 1.6.1 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/ARCHITECTURE.md +18 -8
  3. data/CHANGELOG.md +43 -0
  4. data/README.md +564 -508
  5. data/VERSION +1 -1
  6. data/lib/patient_http/callback_args.rb +53 -48
  7. data/lib/patient_http/callback_validator.rb +11 -7
  8. data/lib/patient_http/class_helper.rb +6 -7
  9. data/lib/patient_http/client.rb +53 -26
  10. data/lib/patient_http/client_pool.rb +134 -39
  11. data/lib/patient_http/completion_executor.rb +20 -20
  12. data/lib/patient_http/configuration.rb +405 -119
  13. data/lib/patient_http/connection_endpoint.rb +150 -0
  14. data/lib/patient_http/encryptor.rb +28 -18
  15. data/lib/patient_http/error.rb +24 -18
  16. data/lib/patient_http/external_storage.rb +42 -38
  17. data/lib/patient_http/http_error.rb +30 -26
  18. data/lib/patient_http/http_headers.rb +35 -29
  19. data/lib/patient_http/immediate_retries.rb +98 -0
  20. data/lib/patient_http/inline_task_handler.rb +15 -10
  21. data/lib/patient_http/lifecycle_manager.rb +39 -40
  22. data/lib/patient_http/outgoing_request.rb +25 -23
  23. data/lib/patient_http/payload.rb +28 -26
  24. data/lib/patient_http/payload_store/active_record_store.rb +31 -34
  25. data/lib/patient_http/payload_store/base.rb +42 -46
  26. data/lib/patient_http/payload_store/file_store.rb +22 -26
  27. data/lib/patient_http/payload_store/redis_store.rb +28 -34
  28. data/lib/patient_http/payload_store/s3_store.rb +25 -28
  29. data/lib/patient_http/payload_store.rb +2 -0
  30. data/lib/patient_http/processor.rb +111 -79
  31. data/lib/patient_http/processor_observer.rb +65 -59
  32. data/lib/patient_http/rails/engine.rb +13 -8
  33. data/lib/patient_http/redirect_error.rb +50 -41
  34. data/lib/patient_http/redirect_helper.rb +38 -38
  35. data/lib/patient_http/request.rb +117 -46
  36. data/lib/patient_http/request_error.rb +47 -42
  37. data/lib/patient_http/request_helper.rb +178 -119
  38. data/lib/patient_http/request_preparer.rb +13 -10
  39. data/lib/patient_http/request_task.rb +115 -84
  40. data/lib/patient_http/request_template.rb +119 -64
  41. data/lib/patient_http/response.rb +58 -52
  42. data/lib/patient_http/response_reader.rb +166 -118
  43. data/lib/patient_http/secret_manager.rb +34 -30
  44. data/lib/patient_http/secret_reference.rb +33 -26
  45. data/lib/patient_http/synchronous_executor.rb +84 -95
  46. data/lib/patient_http/task_handler.rb +23 -19
  47. data/lib/patient_http/time_helper.rb +8 -8
  48. data/lib/patient_http.rb +327 -186
  49. data/patient_http.gemspec +3 -2
  50. metadata +21 -5
@@ -1,31 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PatientHttp
4
- # Mixin that provides a compact API for scheduling async HTTP requests.
4
+ # Adds methods that make async HTTP requests to a class.
5
5
  #
6
- # Include this module in your class to get instance-level and class-level helpers for building
7
- # requests and dispatching them through a registered handler.
6
+ # Include this module to get the `async_get`, `async_head`, `async_post`,
7
+ # `async_put`, `async_patch`, `async_delete`, `async_query`, and
8
+ # `async_request` methods. The methods are available as instance methods and
9
+ # as class methods. They send each request to the registered request handler,
10
+ # so your code doesn't depend on the job system.
8
11
  #
9
- # This module allows you to use the same interface for making HTTP requests while swapping out
10
- # the underlying queueing mechanism for handling responses asynchronously. By registering a
11
- # custom handler, you can integrate with any job queue system (Sidekiq, Solid Queue, etc.)
12
- # without changing your application code that makes HTTP requests. This decouples your request
13
- # interface from your async processing infrastructure.
12
+ # To use the module:
14
13
  #
15
- # The common workflow is:
16
- # 1. Register a global request handler with {PatientHttp.register_handler}.
14
+ # 1. Load a job system integration gem, or register a request handler with
15
+ # {PatientHttp.register_handler}.
17
16
  # 2. Include this module in a class.
18
- # 3. Optionally configure defaults with {.request_template}.
19
- # 4. Call `async_get`, `async_head`, `async_post`, `async_put`, `async_patch`,
20
- # `async_delete`, `async_query`, or `async_request`.
17
+ # 3. Optional: Set shared request options with `request_template`.
18
+ # 4. Call the `async_*` methods.
21
19
  #
22
- # @example Register a handler
23
- # PatientHttp.register_handler do |request:, callback:, callback_args: nil, raise_error_responses: nil|
24
- # # Dispatch the request through your app-specific task/enqueue operation
25
- # # and return the request id
26
- # end
27
- #
28
- # @example Include in a class and enqueue requests
20
+ # @example Include the module and make requests
29
21
  # class ApiClient
30
22
  # include PatientHttp::RequestHelper
31
23
  #
@@ -39,11 +31,9 @@ module PatientHttp
39
31
  extend self
40
32
 
41
33
  class << self
42
- # Hooks helper behavior into the including class.
43
- #
44
- # Extends the class with {.ClassMethods} and initializes template storage.
34
+ # Adds the class methods to a class that includes this module.
45
35
  #
46
- # @param base [Class] class including this module
36
+ # @param base [Class] The class that includes this module.
47
37
  # @return [void]
48
38
  def included(base)
49
39
  base.extend(ClassMethods)
@@ -51,129 +41,172 @@ module PatientHttp
51
41
  end
52
42
  end
53
43
 
44
+ # The `async_*` methods for each HTTP method. They're available as instance
45
+ # methods and as class methods.
54
46
  module HttpMethodHelpers
55
- # Enqueues an asynchronous HTTP GET request.
47
+ # Makes an async GET request.
56
48
  #
57
- # @param uri [String] absolute URL or path (when using a request template)
58
- # @param callback [Class, String] callback class to handle the response
59
- # @param kwargs [Hash] forwarded to `async_request`
60
- # @return [Object] return value from the registered request handler
49
+ # @param uri [String] The absolute URL, or a path relative to the base URL of
50
+ # the request template.
51
+ # @param callback [Class, String] The callback service class, or its name.
52
+ # @param kwargs [Hash] The request options. See `async_request`.
53
+ # @return [Object] The value that the request handler returns.
61
54
  def async_get(uri, callback:, **kwargs)
62
55
  async_request(:get, uri, callback: callback, **kwargs)
63
56
  end
64
57
 
65
- # Enqueues an asynchronous HTTP HEAD request.
58
+ # Makes an async HEAD request.
66
59
  #
67
- # @param uri [String] absolute URL or path (when using a request template)
68
- # @param callback [Class, String] callback class to handle the response
69
- # @param kwargs [Hash] forwarded to `async_request`
70
- # @return [Object] return value from the registered request handler
60
+ # @param uri [String] The absolute URL, or a path relative to the base URL of
61
+ # the request template.
62
+ # @param callback [Class, String] The callback service class, or its name.
63
+ # @param kwargs [Hash] The request options. See `async_request`.
64
+ # @return [Object] The value that the request handler returns.
71
65
  def async_head(uri, callback:, **kwargs)
72
66
  async_request(:head, uri, callback: callback, **kwargs)
73
67
  end
74
68
 
75
- # Enqueues an asynchronous HTTP POST request.
69
+ # Makes an async POST request.
76
70
  #
77
- # @param uri [String] absolute URL or path (when using a request template)
78
- # @param callback [Class, String] callback class to handle the response
79
- # @param kwargs [Hash] forwarded to `async_request`
80
- # @return [Object] return value from the registered request handler
71
+ # @param uri [String] The absolute URL, or a path relative to the base URL of
72
+ # the request template.
73
+ # @param callback [Class, String] The callback service class, or its name.
74
+ # @param kwargs [Hash] The request options. See `async_request`.
75
+ # @return [Object] The value that the request handler returns.
81
76
  def async_post(uri, callback:, **kwargs)
82
77
  async_request(:post, uri, callback: callback, **kwargs)
83
78
  end
84
79
 
85
- # Enqueues an asynchronous HTTP PUT request.
80
+ # Makes an async PUT request.
86
81
  #
87
- # @param uri [String] absolute URL or path (when using a request template)
88
- # @param callback [Class, String] callback class to handle the response
89
- # @param kwargs [Hash] forwarded to `async_request`
90
- # @return [Object] return value from the registered request handler
82
+ # @param uri [String] The absolute URL, or a path relative to the base URL of
83
+ # the request template.
84
+ # @param callback [Class, String] The callback service class, or its name.
85
+ # @param kwargs [Hash] The request options. See `async_request`.
86
+ # @return [Object] The value that the request handler returns.
91
87
  def async_put(uri, callback:, **kwargs)
92
88
  async_request(:put, uri, callback: callback, **kwargs)
93
89
  end
94
90
 
95
- # Enqueues an asynchronous HTTP PATCH request.
91
+ # Makes an async PATCH request.
96
92
  #
97
- # @param uri [String] absolute URL or path (when using a request template)
98
- # @param callback [Class, String] callback class to handle the response
99
- # @param kwargs [Hash] forwarded to `async_request`
100
- # @return [Object] return value from the registered request handler
93
+ # @param uri [String] The absolute URL, or a path relative to the base URL of
94
+ # the request template.
95
+ # @param callback [Class, String] The callback service class, or its name.
96
+ # @param kwargs [Hash] The request options. See `async_request`.
97
+ # @return [Object] The value that the request handler returns.
101
98
  def async_patch(uri, callback:, **kwargs)
102
99
  async_request(:patch, uri, callback: callback, **kwargs)
103
100
  end
104
101
 
105
- # Enqueues an asynchronous HTTP DELETE request.
102
+ # Makes an async DELETE request.
106
103
  #
107
- # @param uri [String] absolute URL or path (when using a request template)
108
- # @param callback [Class, String] callback class to handle the response
109
- # @param kwargs [Hash] forwarded to `async_request`
110
- # @return [Object] return value from the registered request handler
104
+ # @param uri [String] The absolute URL, or a path relative to the base URL of
105
+ # the request template.
106
+ # @param callback [Class, String] The callback service class, or its name.
107
+ # @param kwargs [Hash] The request options. See `async_request`.
108
+ # @return [Object] The value that the request handler returns.
111
109
  def async_delete(uri, callback:, **kwargs)
112
110
  async_request(:delete, uri, callback: callback, **kwargs)
113
111
  end
114
112
 
115
- # Enqueues an asynchronous HTTP QUERY request.
113
+ # Makes an async QUERY request.
116
114
  #
117
- # @param uri [String] absolute URL or path (when using a request template)
118
- # @param callback [Class, String] callback class to handle the response
119
- # @param kwargs [Hash] forwarded to `async_request`
120
- # @return [Object] return value from the registered request handler
115
+ # @param uri [String] The absolute URL, or a path relative to the base URL of
116
+ # the request template.
117
+ # @param callback [Class, String] The callback service class, or its name.
118
+ # @param kwargs [Hash] The request options. See `async_request`.
119
+ # @return [Object] The value that the request handler returns.
121
120
  def async_query(uri, callback:, **kwargs)
122
121
  async_request(:query, uri, callback: callback, **kwargs)
123
122
  end
124
123
  end
125
124
 
125
+ # The class methods that this module adds to a class.
126
126
  module ClassMethods
127
127
  include HttpMethodHelpers
128
128
 
129
- # Defines a default request template for this class.
129
+ # Sets the default request options for this class and its subclasses.
130
130
  #
131
- # Requests created with the helper methods merge these defaults unless explicitly overridden.
131
+ # The `async_*` methods build each request from this template. Options
132
+ # passed to a method override the template.
132
133
  #
133
- # @param base_url [String, nil] optional base URL used to resolve relative request URLs
134
- # @param headers [Hash] default headers for requests
135
- # @param params [Hash, nil] default query parameters for requests
136
- # @param timeout [Float] default timeout in seconds
137
- # @param preprocessors [String, Symbol, Array<String, Symbol>, nil] default names of
138
- # preprocessors registered on the configuration to apply to requests
139
- # @param processor [String, Symbol, nil] default processor name for requests
134
+ # @param base_url [String, nil] The base URL that relative paths are joined
135
+ # with.
136
+ # @param headers [Hash] The default request headers.
137
+ # @param params [Hash, nil] The default query parameters.
138
+ # @param timeout [Numeric, nil] The default request timeout in seconds. If
139
+ # `nil`, the configured `request_timeout` applies.
140
+ # @param read_timeout [Numeric, nil] The default maximum number of seconds to
141
+ # wait for data from the server. If `nil`, the configured `read_timeout`
142
+ # applies.
143
+ # @param max_response_size [Integer, nil] The default maximum response body
144
+ # size in bytes. If `nil`, the configured `max_response_size` applies.
145
+ # @param preprocessors [String, Symbol, Array<String, Symbol>, nil] The names
146
+ # of the default preprocessors.
147
+ # @param processor [String, Symbol, nil] The name of the default processor.
140
148
  # @return [void]
141
- def request_template(base_url: nil, headers: {}, params: nil, timeout: 30, preprocessors: nil, processor: nil)
149
+ def request_template(
150
+ base_url: nil,
151
+ headers: {},
152
+ params: nil,
153
+ timeout: nil,
154
+ read_timeout: nil,
155
+ max_response_size: nil,
156
+ preprocessors: nil,
157
+ processor: nil
158
+ )
142
159
  @patient_http_request_template = RequestTemplate.new(
143
160
  base_url: base_url,
144
161
  headers: headers,
145
162
  params: params,
146
163
  timeout: timeout,
164
+ read_timeout: read_timeout,
165
+ max_response_size: max_response_size,
147
166
  preprocessors: preprocessors,
148
167
  processor: processor
149
168
  )
150
169
  end
151
170
 
152
- # Builds and dispatches an asynchronous HTTP request.
171
+ # Makes an async HTTP request.
153
172
  #
154
- # When a request template is configured, the request is built from the template. Otherwise,
155
- # it is built directly from the provided arguments.
173
+ # If the class has a request template, the template builds the request.
156
174
  #
157
- # @param method [Symbol] HTTP method (`:get`, `:head`, `:post`, `:put`, `:patch`, `:delete`, `:query`)
158
- # @param url [String] absolute URL or path (when using a request template)
159
- # @param callback [Class, String] callback class to handle the response
160
- # @param headers [Hash, nil] request headers
161
- # @param body [String, nil] raw request body
162
- # @param json [Hash, Array, nil] JSON payload encoded by the request layer
163
- # @param params [Hash, nil] query parameters
164
- # @param timeout [Numeric, nil] timeout in seconds for this request
165
- # @param raise_error_responses [Boolean, nil] when true, non-success responses are
166
- # reported as errors
167
- # @param callback_args [Hash, nil] JSON-compatible callback arguments
168
- # @param follow_method_changing_redirects [Boolean, nil] whether to follow a redirect that changes the
169
- # HTTP method (nil uses the configuration default)
170
- # @param redirect_strip_headers [String, Array<String>, nil] header names (case insensitive)
171
- # to strip from redirected requests, in addition to the configured names
172
- # @param preprocessors [String, Symbol, Array<String, Symbol>, nil] names of preprocessors
173
- # registered on the configuration to apply to the request when it is sent
174
- # @param processor [String, Symbol, nil] name of the processor that should execute
175
- # the request
176
- # @return [Object] return value from the registered request handler
175
+ # @param method [Symbol] The HTTP method: `:get`, `:head`, `:post`, `:put`,
176
+ # `:patch`, `:delete`, or `:query`.
177
+ # @param url [String] The absolute URL, or a path relative to the base URL of
178
+ # the request template.
179
+ # @param callback [Class, String] The callback service class, or its name.
180
+ # @param headers [Hash, nil] The request headers.
181
+ # @param body [String, nil] The request body.
182
+ # @param json [Hash, Array, nil] An object to send as a JSON body. Can't be
183
+ # combined with `body`.
184
+ # @param params [Hash, nil] The query parameters to add to the URL.
185
+ # @param timeout [Numeric, nil] The request timeout in seconds.
186
+ # @param read_timeout [Numeric, nil] The maximum number of seconds to wait
187
+ # for data from the server. The timer covers the wait for the response
188
+ # headers and starts again each time a body chunk arrives. If `nil`, the
189
+ # configuration value applies.
190
+ # @param max_response_size [Integer, nil] The maximum response body size in
191
+ # bytes. If `nil`, the configuration value applies.
192
+ # @param raise_error_responses [Boolean, nil] If `true`, non-2xx responses go
193
+ # to the `on_error` callback as an {HttpError}.
194
+ # @param callback_args [Hash, nil] The JSON-compatible arguments to pass to the
195
+ # callback.
196
+ # @param max_redirects [Integer, nil] The maximum number of redirects to
197
+ # follow. If `0`, redirects aren't followed. If `nil`, the configuration
198
+ # value applies.
199
+ # @param follow_method_changing_redirects [Boolean, nil] Whether to follow a
200
+ # redirect that changes the HTTP method. If `nil`, the configuration value
201
+ # applies.
202
+ # @param redirect_strip_headers [String, Array<String>, nil] The names of headers
203
+ # to remove from redirected requests, in addition to the configured names.
204
+ # Names are case insensitive.
205
+ # @param preprocessors [String, Symbol, Array<String, Symbol>, nil] The names of
206
+ # the registered preprocessors that run on the request before it's sent.
207
+ # @param processor [String, Symbol, nil] The name of the processor that runs
208
+ # the request.
209
+ # @return [Object] The value that the request handler returns.
177
210
  def async_request(
178
211
  method,
179
212
  url,
@@ -183,8 +216,11 @@ module PatientHttp
183
216
  json: nil,
184
217
  params: nil,
185
218
  timeout: nil,
219
+ read_timeout: nil,
220
+ max_response_size: nil,
186
221
  raise_error_responses: nil,
187
222
  callback_args: nil,
223
+ max_redirects: nil,
188
224
  follow_method_changing_redirects: nil,
189
225
  redirect_strip_headers: nil,
190
226
  preprocessors: nil,
@@ -197,6 +233,9 @@ module PatientHttp
197
233
  headers: headers,
198
234
  params: params,
199
235
  timeout: timeout,
236
+ read_timeout: read_timeout,
237
+ max_response_size: max_response_size,
238
+ max_redirects: max_redirects,
200
239
  follow_method_changing_redirects: follow_method_changing_redirects,
201
240
  redirect_strip_headers: redirect_strip_headers,
202
241
  preprocessors: preprocessors,
@@ -216,11 +255,11 @@ module PatientHttp
216
255
  )
217
256
  end
218
257
 
219
- # Returns the RequestTemplate defined for this class or its ancestors, or nil if none
220
- # is defined. This allows subclasses to inherit the request template from their parent
221
- # class if they don't define their own.
258
+ # Returns the request template for this class. A subclass without its own
259
+ # template uses the template of its superclass.
222
260
  #
223
- # @return [RequestTemplate, nil] the request template for this class or its ancestors
261
+ # @return [RequestTemplate, nil] The request template, or `nil` if none is
262
+ # set.
224
263
  # @api private
225
264
  def async_request_template
226
265
  return @patient_http_request_template if @patient_http_request_template
@@ -230,30 +269,44 @@ module PatientHttp
230
269
  end
231
270
  end
232
271
 
233
- # Dispatches an asynchronous HTTP request from an instance context.
234
- #
235
- # This delegates to {.ClassMethods#async_request} on the including class.
272
+ # Makes an async HTTP request. This method calls
273
+ # {ClassMethods#async_request} on the class.
236
274
  #
237
- # @param method [Symbol] HTTP method (`:get`, `:head`, `:post`, `:put`, `:patch`, `:delete`, `:query`)
238
- # @param url [String] absolute URL or path (when using a request template)
239
- # @param callback [Class, String] callback class to handle the response
240
- # @param headers [Hash, nil] request headers
241
- # @param body [String, nil] raw request body
242
- # @param json [Hash, Array, nil] JSON payload encoded by the request layer
243
- # @param params [Hash, nil] query parameters
244
- # @param timeout [Numeric, nil] timeout in seconds for this request
245
- # @param raise_error_responses [Boolean, nil] when true, non-success responses are
246
- # reported as errors
247
- # @param callback_args [Hash, nil] JSON-compatible callback arguments
248
- # @param follow_method_changing_redirects [Boolean, nil] whether to follow a redirect that changes the
249
- # HTTP method (nil uses the configuration default)
250
- # @param redirect_strip_headers [String, Array<String>, nil] header names (case insensitive)
251
- # to strip from redirected requests, in addition to the configured names
252
- # @param preprocessors [String, Symbol, Array<String, Symbol>, nil] names of preprocessors
253
- # registered on the configuration to apply to the request when it is sent
254
- # @param processor [String, Symbol, nil] name of the processor that should execute
255
- # the request
256
- # @return [Object] return value from the registered request handler
275
+ # @param method [Symbol] The HTTP method: `:get`, `:head`, `:post`, `:put`,
276
+ # `:patch`, `:delete`, or `:query`.
277
+ # @param url [String] The absolute URL, or a path relative to the base URL of
278
+ # the request template.
279
+ # @param callback [Class, String] The callback service class, or its name.
280
+ # @param headers [Hash, nil] The request headers.
281
+ # @param body [String, nil] The request body.
282
+ # @param json [Hash, Array, nil] An object to send as a JSON body. Can't be
283
+ # combined with `body`.
284
+ # @param params [Hash, nil] The query parameters to add to the URL.
285
+ # @param timeout [Numeric, nil] The request timeout in seconds.
286
+ # @param read_timeout [Numeric, nil] The maximum number of seconds to wait for
287
+ # data from the server. The timer covers the wait for the response headers
288
+ # and starts again each time a body chunk arrives. If `nil`, the
289
+ # configuration value applies.
290
+ # @param max_response_size [Integer, nil] The maximum response body size in
291
+ # bytes. If `nil`, the configuration value applies.
292
+ # @param raise_error_responses [Boolean, nil] If `true`, non-2xx responses go
293
+ # to the `on_error` callback as an {HttpError}.
294
+ # @param callback_args [Hash, nil] The JSON-compatible arguments to pass to the
295
+ # callback.
296
+ # @param max_redirects [Integer, nil] The maximum number of redirects to
297
+ # follow. If `0`, redirects aren't followed. If `nil`, the configuration
298
+ # value applies.
299
+ # @param follow_method_changing_redirects [Boolean, nil] Whether to follow a
300
+ # redirect that changes the HTTP method. If `nil`, the configuration value
301
+ # applies.
302
+ # @param redirect_strip_headers [String, Array<String>, nil] The names of headers
303
+ # to remove from redirected requests, in addition to the configured names.
304
+ # Names are case insensitive.
305
+ # @param preprocessors [String, Symbol, Array<String, Symbol>, nil] The names of
306
+ # the registered preprocessors that run on the request before it's sent.
307
+ # @param processor [String, Symbol, nil] The name of the processor that runs
308
+ # the request.
309
+ # @return [Object] The value that the request handler returns.
257
310
  def async_request(
258
311
  method,
259
312
  url,
@@ -263,8 +316,11 @@ module PatientHttp
263
316
  json: nil,
264
317
  params: nil,
265
318
  timeout: nil,
319
+ read_timeout: nil,
320
+ max_response_size: nil,
266
321
  raise_error_responses: nil,
267
322
  callback_args: nil,
323
+ max_redirects: nil,
268
324
  follow_method_changing_redirects: nil,
269
325
  redirect_strip_headers: nil,
270
326
  preprocessors: nil,
@@ -279,8 +335,11 @@ module PatientHttp
279
335
  json: json,
280
336
  params: params,
281
337
  timeout: timeout,
338
+ read_timeout: read_timeout,
339
+ max_response_size: max_response_size,
282
340
  raise_error_responses: raise_error_responses,
283
341
  callback_args: callback_args,
342
+ max_redirects: max_redirects,
284
343
  follow_method_changing_redirects: follow_method_changing_redirects,
285
344
  redirect_strip_headers: redirect_strip_headers,
286
345
  preprocessors: preprocessors,
@@ -1,29 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PatientHttp
4
- # Prepares a {Request} to be sent: resolves any secret references, sets the
5
- # send-time headers (x-request-id and the default user-agent), and invokes any
6
- # preprocessors attached to the request.
4
+ # Prepares a {Request} to be sent. It resolves the secret references, sets
5
+ # the `x-request-id` and default `user-agent` headers, and runs the
6
+ # preprocessors of the request.
7
7
  class RequestPreparer
8
- # Raised when a request references a preprocessor name that is not registered.
8
+ # Raised when a request refers to a preprocessor that isn't registered.
9
9
  class PreprocessorNotFoundError < StandardError; end
10
10
 
11
- # @param config [Configuration] the configuration holding secrets and preprocessors
11
+ # Creates a request preparer.
12
+ #
13
+ # @param config [Configuration] The configuration that has the secrets and
14
+ # preprocessors.
12
15
  def initialize(config)
13
16
  @config = config
14
17
  end
15
18
 
16
- # Prepare a request for sending.
19
+ # Prepares a request for sending.
17
20
  #
18
21
  # Secret references in the headers and query params are resolved first, then the
19
22
  # x-request-id and default user-agent headers are set, and finally each
20
23
  # preprocessor attached to the request is invoked in order with the outgoing
21
24
  # request. Each preprocessor sees any changes made by the ones before it.
22
25
  #
23
- # @param request [Request] the request to prepare
24
- # @param request_id [String] unique request identifier set as the x-request-id header
25
- # @return [OutgoingRequest] the outgoing request with the final URL and headers
26
- # @raise [PreprocessorNotFoundError] if the request references an unregistered preprocessor
26
+ # @param request [Request] The request to prepare.
27
+ # @param request_id [String] Unique request identifier set as the x-request-id header.
28
+ # @return [OutgoingRequest] The outgoing request with the final URL and headers.
29
+ # @raise [PreprocessorNotFoundError] If the request references an unregistered preprocessor.
27
30
  def prepare(request, request_id)
28
31
  headers = @config.secret_manager.resolve_headers(request.headers.to_h)
29
32
  headers["x-request-id"] = request_id