class Dandy::Request

Public Class Methods

new(route_matcher, container, safe_executor) click to toggle source
# File lib/dandy/request.rb, line 13
def initialize(route_matcher, container, safe_executor)
  @container = container
  @route_matcher = route_matcher
  @safe_executor = safe_executor
end

Public Instance Methods

handle(rack_env) click to toggle source
# File lib/dandy/request.rb, line 19
def handle(rack_env)
  create_scope

  path = rack_env['PATH_INFO']
  request_method = rack_env['REQUEST_METHOD']
  match = @route_matcher.match(path, request_method)

  headers = Hash[
    *rack_env.select {|k, v| k.start_with? 'HTTP_'}
       .collect {|k, v| [k.sub(/^HTTP_/, ''), v]}
       .collect {|k, v| [k.split('_').collect(&:capitalize).join('-'), v]}
       .flatten
  ]

  register_context(headers, :dandy_headers)

  if match.nil?
    result = [404, {'Content-Type' => headers['Accept']}, []]
    release
  else
    status = match.route.http_status || default_http_status(match.route.http_verb)
    register_params(match.params)
    register_status(status)

    query = Rack::Utils.parse_nested_query(rack_env['QUERY_STRING']).to_snake_keys.symbolize_keys
    register_context(query, :dandy_query)

    data = rack_env['rack.parser.result'] ? rack_env['rack.parser.result'].to_snake_keys.deep_symbolize_keys! : {}
    register_context(data, :dandy_data)

    multipart = Rack::Multipart.parse_multipart(rack_env) || {}
    register_context(multipart.values, :dandy_files)

    body = @safe_executor.execute(match.route, headers)

    begin
      release
    rescue Exception => error
      body = @safe_executor.handle_error(match.route, headers, error)
    end

    status = @container.resolve(:dandy_status)
    result = [status, {'Content-Type' => 'application/json'}, [body]]
  end


  result
end

Private Instance Methods

create_scope() click to toggle source
# File lib/dandy/request.rb, line 70
def create_scope
  @container
    .register_instance(self, :dandy_request)
    .using_lifetime(:scope)
    .bound_to(self)
end
default_http_status(http_verb) click to toggle source
# File lib/dandy/request.rb, line 101
def default_http_status(http_verb)
  http_verb == 'POST' ? 201 : 200
end
register_context(params, name) click to toggle source
# File lib/dandy/request.rb, line 77
def register_context(params, name)
  unless params.nil?
    @container.register_instance(params, name)
      .using_lifetime(:scope)
      .bound_to(:dandy_request)
  end
end
register_params(params) click to toggle source
# File lib/dandy/request.rb, line 85
def register_params(params)
  params.keys.each do |key|
    @container
      .register_instance(params[key], key.to_sym)
      .using_lifetime(:scope)
      .bound_to(:dandy_request)
  end
end
register_status(status) click to toggle source
# File lib/dandy/request.rb, line 94
def register_status(status)
  @container
    .register_instance(status, :dandy_status)
    .using_lifetime(:scope)
    .bound_to(:dandy_request)
end