Class: Otto::RouteHandlers::LogicClassHandler

Inherits:
BaseHandler
  • Object
show all
Defined in:
lib/otto/route_handlers/logic_class.rb

Overview

Handler for Logic classes (new in Otto Framework Enhancement)

Logic classes use a constrained signature: initialize(context, params, locale) - context: The authentication strategy result (user info, session data) - params: Merged request parameters (URL params + body + extra_params) - locale: The locale string from env[‘otto.locale’]

IMPORTANT: Logic classes do NOT receive the Rack request or env hash. This is intentional - Logic classes work with clean, authenticated contexts. For endpoints requiring direct request access (sessions, cookies, headers, or logout flows), use controller handlers (Controller#action or Controller.action).

Instance Attribute Summary

Attributes inherited from BaseHandler

#otto_instance, #route_definition

Instance Method Summary collapse

Methods inherited from BaseHandler

#call, #finalize_response, #handle_execution_error, #handle_local_error, #handle_response, #initialize, #setup_request_response, #target_class

Constructor Details

This class inherits a constructor from Otto::RouteHandlers::BaseHandler

Instance Method Details

#extract_logic_params(req, env) ⇒ Hash (protected)

Extract logic parameters including JSON body parsing

Parameters:

  • req (Rack::Request)

    Request object

  • env (Hash)

    Rack environment

Returns:

  • (Hash)

    Parameters for Logic class



64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/otto/route_handlers/logic_class.rb', line 64

def extract_logic_params(req, env)
  # req.params already has extra_params merged and indifferent_params applied
  # by setup_request_response in BaseHandler
  logic_params = req.params.dup

  # Handle JSON request bodies
  if req.content_type&.include?('application/json') && req.body.size.positive?
    logic_params = parse_json_body(req, env, logic_params)
  end

  logic_params
end

#handler_nameString (protected)

Format handler name for Logic routes

Returns:

  • (String)

    Handler name in format “ClassName#call”



108
109
110
# File 'lib/otto/route_handlers/logic_class.rb', line 108

def handler_name
  "#{target_class.name}#call"
end

#invoke_target(req, _res) ⇒ Array (protected)

Invoke Logic class with constrained signature

Parameters:

  • req (Rack::Request)

    Request object

  • res (Rack::Response)

    Response object

Returns:

  • (Array)

    [result, context] for handle_response



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/otto/route_handlers/logic_class.rb', line 27

def invoke_target(req, _res)
  env = req.env

  # Get strategy result (guaranteed to exist from RouteAuthWrapper)
  strategy_result = env['otto.strategy_result']

  # Extract params including JSON body parsing
  logic_params = extract_logic_params(req, env)

  # Get locale
  locale = env['otto.locale'] || 'en'

  # Instantiate Logic class
  logic = target_class.new(strategy_result, logic_params, locale)

  # Execute standard Logic class lifecycle
  logic.raise_concerns if logic.respond_to?(:raise_concerns)

  result = if logic.respond_to?(:process)
             logic.process
           else
             logic.call || logic
           end

  context = {
    logic_instance: logic,
           request: req,
       status_code: logic.respond_to?(:status_code) ? logic.status_code : nil,
  }

  [result, context]
end

#parse_json_body(req, env, logic_params) ⇒ Hash (protected)

Parse JSON request body with error handling

Parameters:

  • req (Rack::Request)

    Request object

  • env (Hash)

    Rack environment

  • logic_params (Hash)

    Current parameters

Returns:

  • (Hash)

    Parameters with JSON merged (or original if parsing fails)



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/otto/route_handlers/logic_class.rb', line 82

def parse_json_body(req, env, logic_params)
  begin
    req.body.rewind
    json_data = JSON.parse(req.body.read)
    logic_params = logic_params.merge(json_data) if json_data.is_a?(Hash)
  rescue JSON::ParserError => e
    # Base context pattern: create once, reuse for correlation
    log_context = Otto::LoggingHelpers.request_context(env)

    Otto.structured_log(:error, 'JSON parsing error',
      log_context.merge(
        handler: handler_name,
        error: e.message,
        error_class: e.class.name,
        duration: Otto::Utils.now_in_μs - @start_time
      ))

    Otto::LoggingHelpers.log_backtrace(e,
      log_context.merge(handler: handler_name))
  end

  logic_params
end