Class: Praxis::Request
- Inherits:
-
Object
- Object
- Praxis::Request
- Defined in:
- lib/praxis/request.rb
Constant Summary collapse
- PATH_VERSION_PREFIX =
'/v'
- CONTENT_TYPE_NAME =
'CONTENT_TYPE'
- PATH_INFO_NAME =
'PATH_INFO'
- REQUEST_METHOD_NAME =
'REQUEST_METHOD'
- QUERY_STRING_NAME =
'QUERY_STRING'
- API_VERSION_HEADER_NAME =
'HTTP_X_API_VERSION'
- API_VERSION_PARAM_NAME =
'api_version'
- API_NO_VERSION_NAME =
'n/a'
- VERSION_USING_DEFAULTS =
%i[header params].freeze
- PATH_VERSION_MATCHER =
DEPRECATED: remove with EndpointDefinition.version using: :path
%r{^#{path_version_prefix}(?<version>[^/]+)/}.freeze
Instance Attribute Summary collapse
-
#action ⇒ Object
Returns the value of attribute action.
-
#env ⇒ Object
readonly
Returns the value of attribute env.
-
#forwarded_from_action ⇒ Object
Returns the value of attribute forwarded_from_action.
-
#headers ⇒ Object
Returns the value of attribute headers.
-
#params ⇒ Object
Returns the value of attribute params.
-
#payload ⇒ Object
Returns the value of attribute payload.
-
#query ⇒ Object
readonly
Returns the value of attribute query.
-
#route_params ⇒ Object
Returns the value of attribute route_params.
Class Method Summary collapse
Instance Method Summary collapse
- #coalesce_inputs! ⇒ Object
-
#content_type ⇒ nil, MediaTypeIdentifier
Determine the content type of this request as indicated by the Content-Type header.
-
#initialize(env) ⇒ Request
constructor
A new instance of Request.
-
#inspect ⇒ Object
Override the inspect instance method of a request, as, by default, the kernel inspect will go nuts traversing the action and app_instance and therefore all associated instance variables reachable through that.
- #load_headers(context) ⇒ Object
- #load_params(context) ⇒ Object
- #load_payload(context) ⇒ Object
-
#media_type ⇒ String
The media type (type/subtype+suffix) portion of the Content-Type header without any media type parameters.
- #params_hash ⇒ Object
- #path ⇒ Object
- #path_version_matcher ⇒ Object
- #raw_params ⇒ Object
- #raw_payload ⇒ Object
-
#unmatched_versions ⇒ Object
versions that matched all the conditions of the request (except its version).
- #validate_headers(context) ⇒ Object
- #validate_params(context) ⇒ Object
- #validate_payload(context) ⇒ Object
- #verb ⇒ Object
- #version ⇒ Object
Constructor Details
#initialize(env) ⇒ Request
Returns a new instance of Request.
18 19 20 21 22 |
# File 'lib/praxis/request.rb', line 18 def initialize(env) @env = env @query = Rack::Utils.parse_nested_query(env[QUERY_STRING_NAME]) @route_params = {} end |
Instance Attribute Details
#action ⇒ Object
Returns the value of attribute action.
6 7 8 |
# File 'lib/praxis/request.rb', line 6 def action @action end |
#env ⇒ Object (readonly)
Returns the value of attribute env.
5 6 7 |
# File 'lib/praxis/request.rb', line 5 def env @env end |
#forwarded_from_action ⇒ Object
Returns the value of attribute forwarded_from_action.
6 7 8 |
# File 'lib/praxis/request.rb', line 6 def forwarded_from_action @forwarded_from_action end |
#headers ⇒ Object
Returns the value of attribute headers.
6 7 8 |
# File 'lib/praxis/request.rb', line 6 def headers @headers end |
#params ⇒ Object
Returns the value of attribute params.
6 7 8 |
# File 'lib/praxis/request.rb', line 6 def params @params end |
#payload ⇒ Object
Returns the value of attribute payload.
6 7 8 |
# File 'lib/praxis/request.rb', line 6 def payload @payload end |
#query ⇒ Object (readonly)
Returns the value of attribute query.
5 6 7 |
# File 'lib/praxis/request.rb', line 5 def query @query end |
#route_params ⇒ Object
Returns the value of attribute route_params.
6 7 8 |
# File 'lib/praxis/request.rb', line 6 def route_params @route_params end |
Class Method Details
.path_version_prefix ⇒ Object
79 80 81 |
# File 'lib/praxis/request.rb', line 79 def self.path_version_prefix PATH_VERSION_PREFIX end |
Instance Method Details
#coalesce_inputs! ⇒ Object
74 75 76 77 |
# File 'lib/praxis/request.rb', line 74 def coalesce_inputs! raw_params raw_payload end |
#content_type ⇒ nil, MediaTypeIdentifier
Determine the content type of this request as indicated by the Content-Type header.
27 28 29 30 |
# File 'lib/praxis/request.rb', line 27 def content_type header = @env[CONTENT_TYPE_NAME] @content_type ||= (header && MediaTypeIdentifier.load(header)).freeze end |
#inspect ⇒ Object
Override the inspect instance method of a request, as, by default, the kernel inspect will go nuts traversing the action and app_instance and therefore all associated instance variables reachable through that
186 187 188 |
# File 'lib/praxis/request.rb', line 186 def inspect "#<#{self.class}##{object_id} @action=#{@action.inspect} @params=#{@params.inspect}>" end |
#load_headers(context) ⇒ Object
113 114 115 116 117 118 119 120 |
# File 'lib/praxis/request.rb', line 113 def load_headers(context) return unless action.headers defined_headers = action.precomputed_header_keys_for_rack.each_with_object({}) do |(upper, original), hash| hash[original] = env[upper] if env.key? upper end self.headers = action.headers.load(defined_headers, context) end |
#load_params(context) ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/praxis/request.rb', line 122 def load_params(context) return unless action.params self.params = action.params.load(raw_params, context) return unless forwarded_from_action && content_type # If it is coming from a forwarded action, and has a content type, let's parse it, and merge it to the params as well raw = if (handler = Praxis::Application.instance.handlers[content_type.handler_name]) handler.parse(raw_payload) else # TODO: is this a good default? raw_payload end loaded_payload = forwarded_from_action.payload.load(raw, context, content_type: content_type.to_s) self.params = params.merge(loaded_payload) end |
#load_payload(context) ⇒ Object
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/praxis/request.rb', line 139 def load_payload(context) return unless action.payload return if content_type.nil? return if action.sister_post_action # Do not load payloads for a special GET action with a sister post one...(cause we've loaded into the params) raw = if (handler = Praxis::Application.instance.handlers[content_type.handler_name]) handler.parse(raw_payload) else # TODO: is this a good default? raw_payload end self.payload = action.payload.load(raw, context, content_type: content_type.to_s) end |
#media_type ⇒ String
The media type (type/subtype+suffix) portion of the Content-Type header without any media type parameters. e.g., when Content-Type is “text/plain;charset=utf-8”, the media-type is “text/plain”.
For more information on the use of media types in HTTP, see: www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7
41 42 43 |
# File 'lib/praxis/request.rb', line 41 def media_type content_type.without_parameters.to_s end |
#params_hash ⇒ Object
49 50 51 52 53 |
# File 'lib/praxis/request.rb', line 49 def params_hash return {} if params.nil? params.attributes end |
#path ⇒ Object
45 46 47 |
# File 'lib/praxis/request.rb', line 45 def path @env[PATH_INFO_NAME] end |
#path_version_matcher ⇒ Object
86 87 88 89 90 91 92 93 |
# File 'lib/praxis/request.rb', line 86 def path_version_matcher if Application.instance.versioning_scheme == :path matcher = Mustermann.new("#{ApiDefinition.instance.info.base_path}*") matcher.params(path)[API_VERSION_PARAM_NAME] else PATH_VERSION_MATCHER.match(path)[:version] end end |
#raw_params ⇒ Object
59 60 61 62 63 64 65 |
# File 'lib/praxis/request.rb', line 59 def raw_params @raw_params ||= begin params = query.merge(route_params) params.delete(API_VERSION_PARAM_NAME) params end end |
#raw_payload ⇒ Object
67 68 69 70 71 72 |
# File 'lib/praxis/request.rb', line 67 def raw_payload @raw_payload ||= if (input = env['rack.input'].read) env['rack.input'].rewind input end end |
#unmatched_versions ⇒ Object
versions that matched all the conditions of the request (except its version)
180 181 182 |
# File 'lib/praxis/request.rb', line 180 def unmatched_versions @unmatched_versions ||= Set.new end |
#validate_headers(context) ⇒ Object
155 156 157 158 159 160 161 |
# File 'lib/praxis/request.rb', line 155 def validate_headers(context) return [] unless action.headers return ["Attribute #{Attributor.humanize_context(context)} is required."] if action.headers.[:required] == true && headers.nil? action.headers.validate(headers, context) end |
#validate_params(context) ⇒ Object
163 164 165 166 167 168 169 |
# File 'lib/praxis/request.rb', line 163 def validate_params(context) return [] unless action.params return ["Attribute #{Attributor.humanize_context(context)} is required."] if action.params.[:required] == true && params.nil? action.params.validate(params, context) end |
#validate_payload(context) ⇒ Object
171 172 173 174 175 176 177 |
# File 'lib/praxis/request.rb', line 171 def validate_payload(context) return [] unless action.payload return ["Attribute #{Attributor.humanize_context(context)} is required."] if action.payload.[:required] == true && payload.nil? action.payload.validate(payload, context) end |
#verb ⇒ Object
55 56 57 |
# File 'lib/praxis/request.rb', line 55 def verb @env[REQUEST_METHOD_NAME] end |
#version ⇒ Object
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/praxis/request.rb', line 95 def version result = nil Array(Application.instance.versioning_scheme).find do |mode| case mode when :header result = env[API_VERSION_HEADER_NAME] when :params result = @query[API_VERSION_PARAM_NAME] when :path result = path_version_matcher else raise "Unknown method for retrieving the API version: #{mode}" end end result || API_NO_VERSION_NAME end |