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']
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 ⇒ String
Content-Type for this request, taken from request headers if present, or the request media_type.
-
#content_type_attrs ⇒ ::Ur::ContentTypeAttrs
Content type attributes for this request's Content-Type.
-
#content_type_header ⇒ String
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
- #request_schema_class(media_type: self.media_type) ⇒ Class subclassing JSI::Base
-
#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.
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/scorpio/request.rb', line 117 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)
143 144 145 |
# File 'lib/scorpio/request.rb', line 143 def operation @operation end |
Class Method Details
.best_media_type(media_types) ⇒ Object
4 5 6 7 8 9 10 |
# File 'lib/scorpio/request.rb', line 4 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 ⇒ String
Returns Content-Type for this request, taken from request headers if present, or the request media_type.
208 209 210 |
# File 'lib/scorpio/request.rb', line 208 def content_type content_type_header || media_type end |
#content_type_attrs ⇒ ::Ur::ContentTypeAttrs
Returns content type attributes for this request's Content-Type.
194 195 196 |
# File 'lib/scorpio/request.rb', line 194 def content_type_attrs Ur::ContentTypeAttrs.new(content_type) end |
#content_type_header ⇒ String
Returns the value of the request Content-Type header.
199 200 201 202 203 204 |
# File 'lib/scorpio/request.rb', line 199 def content_type_header headers.each do |k, v| return 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
361 362 363 364 365 366 367 368 369 370 |
# File 'lib/scorpio/request.rb', line 361 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.
227 228 229 230 231 232 233 234 235 236 |
# File 'lib/scorpio/request.rb', line 227 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, ur_class: Scorpio::Ur, 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.
253 254 255 256 |
# File 'lib/scorpio/request.rb', line 253 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.
308 309 310 311 312 313 314 315 316 317 318 319 320 321 |
# File 'lib/scorpio/request.rb', line 308 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.
151 152 153 |
# File 'lib/scorpio/request.rb', line 151 def http_method operation.http_method.downcase.to_sym end |
#openapi_document ⇒ Scorpio::OpenAPI::Document
146 147 148 |
# File 'lib/scorpio/request.rb', line 146 def openapi_document operation.openapi_document end |
#param_for(name) ⇒ #to_hash?
260 261 262 263 264 265 266 267 268 269 270 271 272 |
# File 'lib/scorpio/request.rb', line 260 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
276 277 278 |
# File 'lib/scorpio/request.rb', line 276 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.
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/scorpio/request.rb', line 163 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.
157 158 159 |
# File 'lib/scorpio/request.rb', line 157 def path_template operation.path_template end |
#request_schema(media_type: self.media_type) ⇒ ::JSI::Schema
213 214 215 |
# File 'lib/scorpio/request.rb', line 213 def request_schema(media_type: self.media_type) operation.request_schema(media_type: media_type) end |
#request_schema_class(media_type: self.media_type) ⇒ Class subclassing JSI::Base
218 219 220 |
# File 'lib/scorpio/request.rb', line 218 def request_schema_class(media_type: self.media_type) JSI.class_for_schema(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.
349 350 351 352 353 |
# File 'lib/scorpio/request.rb', line 349 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.
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 |
# File 'lib/scorpio/request.rb', line 326 def run_ur headers = {} if user_agent headers['User-Agent'] = user_agent end if media_type && !content_type_header headers['Content-Type'] = media_type 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.
244 245 246 247 248 |
# File 'lib/scorpio/request.rb', line 244 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.
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 |
# File 'lib/scorpio/request.rb', line 286 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.
184 185 186 187 188 189 190 191 |
# File 'lib/scorpio/request.rb', line 184 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 |