Class: Scorpio::Request
- Inherits:
-
Object
- Object
- Scorpio::Request
- Includes:
- Configurables
- Defined in:
- lib/scorpio/request.rb
Defined Under Namespace
Modules: Configurables
Constant Summary collapse
- SUPPORTED_REQUEST_MEDIA_TYPES =
['application/json', 'application/x-www-form-urlencoded']
- FALLBACK_CONTENT_TYPE =
'application/x-www-form-urlencoded'
Instance Attribute Summary collapse
Attributes included from Configurables
#base_url, #body, #body_object, #faraday_adapter, #faraday_builder, #headers, #logger, #media_type, #path_params, #query_params, #scheme, #server, #server_variables, #user_agent
Class Method Summary collapse
Instance Method Summary collapse
-
#content_type ⇒ ::Ur::ContentType
Content-Type for this request, taken from request headers if present, or the request media_type.
-
#content_type_header ⇒ ::Ur::ContentType
The value of the request Content-Type header.
-
#each_page_ur(next_page:, raise_on_http_error: true) {|Scorpio::Ur| ... } ⇒ void
todo make a proper iterator interface.
-
#faraday_connection(yield_ur = nil) ⇒ ::Faraday::Connection
builds a Faraday connection with this Request's faraday_builder and faraday_adapter.
-
#get_param(name) ⇒ Object
The value of the named parameter on this request.
-
#get_param_from(param_in, name) ⇒ Object
The value of the named parameter on this request.
-
#http_method ⇒ Symbol
The http method for this request - :get, :post, etc.
-
#initialize(operation, configuration = {}, &b) ⇒ Request
constructor
A new instance of Request.
- #openapi_document ⇒ Scorpio::OpenAPI::Document
- #param_for(name) ⇒ #to_hash?
- #param_for!(name) ⇒ #to_hash
-
#path ⇒ Addressable::URI
An Addressable::URI containing only the path to append to the base_url for this request.
-
#path_template ⇒ Addressable::Template
The template for the request's path, to be expanded with path_params and appended to the request's base_url.
- #request_schema(media_type: self.media_type) ⇒ ::JSI::Schema
-
#run ⇒ Object
runs this request.
-
#run_ur ⇒ Scorpio::Ur
runs this request and returns the full representation of the request that was run and its response.
-
#set_param(name, value) ⇒ Object
if there is only one parameter with the given name, of any sort, this will set it.
-
#set_param_from(param_in, name, value) ⇒ Object
Echoes the value param.
-
#url ⇒ Addressable::URI
The full URL for this request.
Constructor Details
#initialize(operation, configuration = {}, &b) ⇒ Request
Returns a new instance of Request.
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/scorpio/request.rb', line 118 def initialize(operation, configuration = {}, &b) @operation = operation configuration = JSI.stringify_symbol_keys(configuration) params_set = Set.new # the set of params that have been set # do the Configurables first configuration.each do |name, value| if Configurables.public_method_defined?("#{name}=") Configurables.instance_method("#{name}=").bind(self).call(value) params_set << name end end # then do other top-level params configuration.reject { |name, _| params_set.include?(name) }.each do |name, value| param = param_for(name) || raise(ArgumentError, "unrecognized configuration value passed: #{name.inspect}") set_param_from(param['in'], param['name'], value) end extend operation.request_accessor_module if block_given? yield self end end |
Instance Attribute Details
#operation ⇒ Scorpio::OpenAPI::Operation (readonly)
144 145 146 |
# File 'lib/scorpio/request.rb', line 144 def operation @operation end |
Class Method Details
.best_media_type(media_types) ⇒ Object
6 7 8 9 10 11 12 |
# File 'lib/scorpio/request.rb', line 6 def self.best_media_type(media_types) if media_types.size == 1 media_types.first else SUPPORTED_REQUEST_MEDIA_TYPES.detect { |mt| media_types.include?(mt) } end end |
Instance Method Details
#content_type ⇒ ::Ur::ContentType
Returns Content-Type for this request, taken from request headers if present, or the request media_type.
204 205 206 |
# File 'lib/scorpio/request.rb', line 204 def content_type content_type_header || (media_type ? ::Ur::ContentType.new(media_type) : nil) end |
#content_type_header ⇒ ::Ur::ContentType
Returns the value of the request Content-Type header.
195 196 197 198 199 200 |
# File 'lib/scorpio/request.rb', line 195 def content_type_header headers.each do |k, v| return ::Ur::ContentType.new(v) if k =~ /\Acontent[-_]type\z/i end nil end |
#each_page_ur(next_page:, raise_on_http_error: true) {|Scorpio::Ur| ... } ⇒ void
This method returns an undefined value.
todo make a proper iterator interface
359 360 361 362 363 364 365 366 367 368 |
# File 'lib/scorpio/request.rb', line 359 def each_page_ur(next_page: , raise_on_http_error: true) return to_enum(__method__, next_page: next_page, raise_on_http_error: raise_on_http_error) unless block_given? page_ur = run_ur while page_ur page_ur.raise_on_http_error if raise_on_http_error yield page_ur page_ur = next_page.call(page_ur) end nil end |
#faraday_connection(yield_ur = nil) ⇒ ::Faraday::Connection
builds a Faraday connection with this Request's faraday_builder and faraday_adapter. passes a given proc yield_ur to middleware to yield an Ur for requests made with the connection.
218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/scorpio/request.rb', line 218 def faraday_connection(yield_ur = nil) Faraday.new do |faraday_connection| faraday_builder.call(faraday_connection) if yield_ur -> { ::Ur::Faraday }.() # autoload trigger faraday_connection.response(:yield_ur, schemas: Set[Scorpio::Ur.schema], logger: self.logger, &yield_ur) end faraday_connection.adapter(*faraday_adapter) end end |
#get_param(name) ⇒ Object
Returns the value of the named parameter on this request.
245 246 247 248 |
# File 'lib/scorpio/request.rb', line 245 def get_param(name) param = param_for!(name) get_param_from(param['in'], param['name']) end |
#get_param_from(param_in, name) ⇒ Object
Returns the value of the named parameter on this request.
300 301 302 303 304 305 306 307 308 309 310 311 312 313 |
# File 'lib/scorpio/request.rb', line 300 def get_param_from(param_in, name) if param_in == 'path' path_params[name] elsif param_in == 'query' query_params ? query_params[name] : nil elsif param_in == 'header' _, value = headers.detect { |headername, _| headername.downcase == name.downcase } value elsif param_in == 'cookie' raise(NotImplementedError, "cookies not implemented: #{name.inspect}") else raise(ArgumentError, "cannot get param from param_in = #{param_in.inspect} (name: #{name.pretty_inspect.chomp})") end end |
#http_method ⇒ Symbol
Returns the http method for this request - :get, :post, etc.
152 153 154 |
# File 'lib/scorpio/request.rb', line 152 def http_method operation.http_method.downcase.to_sym end |
#openapi_document ⇒ Scorpio::OpenAPI::Document
147 148 149 |
# File 'lib/scorpio/request.rb', line 147 def openapi_document operation.openapi_document end |
#param_for(name) ⇒ #to_hash?
252 253 254 255 256 257 258 259 260 261 262 263 264 |
# File 'lib/scorpio/request.rb', line 252 def param_for(name) name = name.to_s if name.is_a?(Symbol) params = operation.inferred_parameters.select { |p| p['name'] == name } if params.size == 1 params.first elsif params.size == 0 nil else raise(AmbiguousParameter.new( "There are multiple parameters for #{name}. matched parameters were: #{params.pretty_inspect.chomp}" ).tap { |e| e.name = name }) end end |
#param_for!(name) ⇒ #to_hash
268 269 270 |
# File 'lib/scorpio/request.rb', line 268 def param_for!(name) param_for(name) || raise(ParameterError, "There is no parameter named #{name} on operation #{operation.human_id}:\n#{operation.pretty_inspect.chomp}") end |
#path ⇒ Addressable::URI
Returns an Addressable::URI containing only the path to append to the base_url for this request.
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/scorpio/request.rb', line 164 def path path_params = JSI.stringify_symbol_keys(self.path_params) missing_variables = path_template.variables - path_params.keys if missing_variables.any? raise(ArgumentError, "path #{operation.path_template_str} for operation #{operation.human_id} requires path_params " + "which were missing: #{missing_variables.inspect}") end empty_variables = path_template.variables.select { |v| path_params[v].to_s.empty? } if empty_variables.any? raise(ArgumentError, "path #{operation.path_template_str} for operation #{operation.human_id} requires path_params " + "which were empty: #{empty_variables.inspect}") end path_template.(path_params).tap do |path| if query_params path.query_values = query_params end end end |
#path_template ⇒ Addressable::Template
Returns the template for the request's path, to be expanded with path_params and appended to the request's base_url.
158 159 160 |
# File 'lib/scorpio/request.rb', line 158 def path_template operation.path_template end |
#request_schema(media_type: self.media_type) ⇒ ::JSI::Schema
209 210 211 |
# File 'lib/scorpio/request.rb', line 209 def request_schema(media_type: self.media_type) operation.request_schema(media_type: media_type) end |
#run ⇒ Object
runs this request. returns the response body object - that is, the response body parsed according to an understood media type, and instantiated with the applicable response schema if one is specified. see Scorpio::Response#body_object for more detail.
347 348 349 350 351 |
# File 'lib/scorpio/request.rb', line 347 def run ur = run_ur ur.raise_on_http_error ur.response.body_object end |
#run_ur ⇒ Scorpio::Ur
runs this request and returns the full representation of the request that was run and its response.
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 |
# File 'lib/scorpio/request.rb', line 318 def run_ur headers = {} if user_agent headers['User-Agent'] = user_agent end if !content_type_header if media_type headers['Content-Type'] = media_type else # I'd rather not have a default content-type, but if none is set then the HTTP adapter sets this to # application/x-www-form-urlencoded and issues a warning about it. headers['Content-Type'] = FALLBACK_CONTENT_TYPE end end if self.headers headers.update(self.headers) end ur = nil faraday_connection(-> (yur) { ur = yur }).run_request(http_method, url, body, headers) ur.scorpio_request = self ur end |
#set_param(name, value) ⇒ Object
if there is only one parameter with the given name, of any sort, this will set it.
236 237 238 239 240 |
# File 'lib/scorpio/request.rb', line 236 def set_param(name, value) param = param_for!(name) set_param_from(param['in'], param['name'], value) value end |
#set_param_from(param_in, name, value) ⇒ Object
Returns echoes the value param.
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
# File 'lib/scorpio/request.rb', line 278 def set_param_from(param_in, name, value) param_in = param_in.to_s if param_in.is_a?(Symbol) name = name.to_s if name.is_a?(Symbol) if param_in == 'path' self.path_params = self.path_params.merge(name => value) elsif param_in == 'query' self.query_params = (self.query_params || {}).merge(name => value) elsif param_in == 'header' self.headers = self.headers.merge(name => value) elsif param_in == 'cookie' raise(NotImplementedError, "cookies not implemented: #{name.inspect} => #{value.inspect}") else raise(ArgumentError, "cannot set param from param_in = #{param_in.inspect} (name: #{name.pretty_inspect.chomp}, value: #{value.pretty_inspect.chomp})") end value end |
#url ⇒ Addressable::URI
Returns the full URL for this request.
185 186 187 188 189 190 191 192 |
# File 'lib/scorpio/request.rb', line 185 def url unless base_url raise(ArgumentError, "no base_url has been specified for request") end # we do not use Addressable::URI#join as the paths should just be concatenated, not resolved. # we use File.join just to deal with consecutive slashes. Addressable::URI.parse(File.join(base_url, path)) end |