Class: Praxis::Request

Inherits:
Object
  • Object
show all
Defined in:
lib/praxis/request.rb

Constant Summary collapse

PATH_VERSION_PREFIX =
"/v".freeze
CONTENT_TYPE_NAME =
'CONTENT_TYPE'.freeze
PATH_INFO_NAME =
'PATH_INFO'.freeze
REQUEST_METHOD_NAME =
'REQUEST_METHOD'.freeze
QUERY_STRING_NAME =
'QUERY_STRING'.freeze
API_VERSION_HEADER_NAME =
"HTTP_X_API_VERSION".freeze
API_VERSION_PARAM_NAME =
'api_version'.freeze
API_NO_VERSION_NAME =
'n/a'.freeze
VERSION_USING_DEFAULTS =
[:header, :params].freeze
PATH_VERSION_MATCHER =

DEPRECATED: remove with ResourceDefinition.version using: :path

%r{^#{self.path_version_prefix}(?<version>[^\/]+)\/}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(env) ⇒ Request

Returns a new instance of Request.



17
18
19
20
21
# File 'lib/praxis/request.rb', line 17

def initialize(env)
  @env = env
  @query = Rack::Utils.parse_nested_query(env[QUERY_STRING_NAME])
  @route_params = {}
end

Instance Attribute Details

#actionObject

Returns the value of attribute action.



5
6
7
# File 'lib/praxis/request.rb', line 5

def action
  @action
end

#envObject (readonly)

Returns the value of attribute env.



4
5
6
# File 'lib/praxis/request.rb', line 4

def env
  @env
end

#headersObject

Returns the value of attribute headers.



48
49
50
# File 'lib/praxis/request.rb', line 48

def headers
  @headers
end

#paramsObject

Returns the value of attribute params.



48
49
50
# File 'lib/praxis/request.rb', line 48

def params
  @params
end

#payloadObject

Returns the value of attribute payload.



48
49
50
# File 'lib/praxis/request.rb', line 48

def payload
  @payload
end

#queryObject (readonly)

Returns the value of attribute query.



4
5
6
# File 'lib/praxis/request.rb', line 4

def query
  @query
end

#route_paramsObject

Returns the value of attribute route_params.



5
6
7
# File 'lib/praxis/request.rb', line 5

def route_params
  @route_params
end

Class Method Details

.path_version_prefixObject



81
82
83
# File 'lib/praxis/request.rb', line 81

def self.path_version_prefix
  PATH_VERSION_PREFIX
end

Instance Method Details

#coalesce_inputs!Object



76
77
78
79
# File 'lib/praxis/request.rb', line 76

def coalesce_inputs!
  self.raw_params
  self.raw_payload
end

#content_typenil, MediaTypeIdentifier

Determine the content type of this request as indicated by the Content-Type header.

Returns:



26
27
28
29
# File 'lib/praxis/request.rb', line 26

def content_type
  header = @env[CONTENT_TYPE_NAME]
  @content_type ||= (header && MediaTypeIdentifier.load(header)).freeze
end

#load_headers(context) ⇒ Object



115
116
117
118
119
120
121
# File 'lib/praxis/request.rb', line 115

def load_headers(context)
  return unless action.headers
  defined_headers = action.precomputed_header_keys_for_rack.each_with_object(Hash.new) do |(upper, original), hash|
    hash[original] = self.env[upper] if self.env.has_key? upper
  end
  self.headers = action.headers.load(defined_headers, context)
end

#load_params(context) ⇒ Object



123
124
125
126
# File 'lib/praxis/request.rb', line 123

def load_params(context)
  return unless action.params
  self.params = action.params.load(self.raw_params, context)
end

#load_payload(context) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/praxis/request.rb', line 128

def load_payload(context)
  return unless action.payload
  return if content_type.nil?

  raw = if (handler = Praxis::Application.instance.handlers[content_type.handler_name])
    handler.parse(self.raw_payload)
  else
    # TODO is this a good default?
    self.raw_payload
  end

  self.payload = action.payload.load(raw, context, content_type: content_type.to_s)
end

#media_typeString

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

Returns:

  • (String)

See Also:



40
41
42
# File 'lib/praxis/request.rb', line 40

def media_type
  content_type.without_parameters.to_s
end

#params_hashObject



50
51
52
53
# File 'lib/praxis/request.rb', line 50

def params_hash
  return {} if params.nil?
  params.attributes
end

#pathObject



44
45
46
# File 'lib/praxis/request.rb', line 44

def path
  @env[PATH_INFO_NAME]
end

#path_version_matcherObject



88
89
90
91
92
93
94
95
# File 'lib/praxis/request.rb', line 88

def path_version_matcher
  if Application.instance.versioning_scheme == :path
    matcher = Mustermann.new(ApiDefinition.instance.info.base_path + '*')
    matcher.params(self.path)[API_VERSION_PARAM_NAME]
  else
    PATH_VERSION_MATCHER.match(self.path)[:version]
  end
end

#raw_paramsObject



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_payloadObject



67
68
69
70
71
72
73
74
# File 'lib/praxis/request.rb', line 67

def raw_payload
  @raw_payload ||= begin
    if (input = env['rack.input'.freeze].read)
      env['rack.input'.freeze].rewind
      input
    end
  end
end

#unmatched_versionsObject

versions that matched all the conditions of the request (except its version)



161
162
163
# File 'lib/praxis/request.rb', line 161

def unmatched_versions
  @unmatched_versions ||= Set.new
end

#validate_headers(context) ⇒ Object



142
143
144
145
146
# File 'lib/praxis/request.rb', line 142

def validate_headers(context)
  return [] unless action.headers

  action.headers.validate(self.headers, context)
end

#validate_params(context) ⇒ Object



148
149
150
151
152
# File 'lib/praxis/request.rb', line 148

def validate_params(context)
  return [] unless action.params

  action.params.validate(self.params, context)
end

#validate_payload(context) ⇒ Object



154
155
156
157
158
# File 'lib/praxis/request.rb', line 154

def validate_payload(context)
  return [] unless action.payload

  action.payload.validate(self.payload, context)
end

#verbObject



55
56
57
# File 'lib/praxis/request.rb', line 55

def verb
  @env[REQUEST_METHOD_NAME]
end

#versionObject



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/praxis/request.rb', line 97

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 = self.path_version_matcher
    else
      raise "Unknown method for retrieving the API version: #{mode}"
    end
  end
  return result || API_NO_VERSION_NAME
end