Class: Jets::Controller::Base

Inherits:
Lambda::Functions show all
Includes:
ActiveSupport::Rescuable, Authorization, Callbacks, Cookies, ForgeryProtection, Layout, Params, Rendering, Router::Helpers
Defined in:
lib/jets/controller/base.rb

Constant Summary

Constants included from Router::Helpers::CoreHelper

Router::Helpers::CoreHelper::CONTROLLER_DELEGATES

Instance Attribute Summary collapse

Attributes inherited from Lambda::Functions

#context, #event, #meth

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Rendering

#actual_host, #add_stage_name, #adjust_content_type!, #default_layout, #ensure_render, #managed_options, #normalize_options, #render, #url_for

Methods included from Redirection

#ensure_protocol, #redirect_back, #redirect_to

Methods included from Params

#body_params, #filtered_parameters, #params, #path_params, #query_params, #request_params, #unescape_recursively

Methods included from Router::Helpers::NamedRoutesHelper

clear!

Methods included from Router::Helpers::CoreHelper

#polymorphic_path

Methods included from ForgeryProtection

#verify_authenticity_token

Methods included from Cookies

#cookies

Methods inherited from Lambda::Functions

inherited, output_keys, subclasses

Methods included from Lambda::Dsl

#lambda_functions

Constructor Details

#initialize(event, context = {}, meth) ⇒ Base

Returns a new instance of Base.



21
22
23
24
25
# File 'lib/jets/controller/base.rb', line 21

def initialize(event, context={}, meth)
  super
  @request = Request.new(event, context)
  @response = Response.new
end

Instance Attribute Details

#requestObject (readonly)

Returns the value of attribute request.



19
20
21
# File 'lib/jets/controller/base.rb', line 19

def request
  @request
end

#responseObject (readonly)

Returns the value of attribute response.



19
20
21
# File 'lib/jets/controller/base.rb', line 19

def response
  @response
end

#sessionObject

Returns the value of attribute session.



20
21
22
# File 'lib/jets/controller/base.rb', line 20

def session
  @session
end

Class Method Details

.helper_method(*meths) ⇒ Object



168
169
170
171
172
# File 'lib/jets/controller/base.rb', line 168

def helper_method(*meths)
  meths.each do |meth|
    Jets::Router::Helpers.define_helper_method(meth)
  end
end

.internal(value = nil) ⇒ Object



160
161
162
163
164
165
166
# File 'lib/jets/controller/base.rb', line 160

def internal(value=nil)
  if !value.nil?
    self.internal_controller = value
  else
    self.internal_controller
  end
end

.process(event, context = {}, meth) ⇒ Object

Overrides Base.process



28
29
30
31
32
33
34
35
36
# File 'lib/jets/controller/base.rb', line 28

def self.process(event, context={}, meth)
  controller = new(event, context, meth)
  # Using send because process! is private method in Jets::RackController so
  # it doesnt create a lambda function.  It's doesnt matter what scope process!
  # is in Controller::Base because Jets lambda functions inheritance doesnt
  # include methods in Controller::Base.
  # TODO: Can process! be a protected method to avoid this?
  controller.send(:process!)
end

Instance Method Details

#action_nameObject



154
155
156
# File 'lib/jets/controller/base.rb', line 154

def action_name
  @meth
end

#controller_nameObject



150
151
152
# File 'lib/jets/controller/base.rb', line 150

def controller_name
  self.class.to_s.underscore
end

#controller_pathsObject



140
141
142
143
144
145
146
147
148
# File 'lib/jets/controller/base.rb', line 140

def controller_paths
  paths = []
  klass = self.class
  while klass != Jets::Controller::Base
    paths << klass.controller_path
    klass = klass.superclass
  end
  paths
end

#dispatch!Object

One key difference between process! vs dispatch!

process! - takes the request through the middleware stack
dispatch! - does not

dispatch! is useful for megamode or mounted applications



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/jets/controller/base.rb', line 77

def dispatch!
  t1 = Time.now
  log_start

  begin
    if run_before_actions(break_if: -> { @rendered })
      send(@meth)
      action_completed = true
    else
      Jets.logger.info "Filter chain halted as #{@last_callback_name} rendered or redirected"
    end

    triplet = ensure_render
    run_after_actions if action_completed
  rescue Exception => exception
    rescue_with_handler(exception) || raise
    triplet = ensure_render
  end

  took = Time.now - t1
  status = triplet[0]
  log_finish(status: status, took: took)
  triplet # status, headers, body
end

#event_logObject



118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/jets/controller/base.rb', line 118

def event_log
  display_event = @event.dup

  if @event['isBase64Encoded']
    display_event['body'] = '[BASE64_ENCODED]'
  else
    display_event['body'] = parameter_filter.filter_json(display_event['body'])
  end

  display_event["queryStringParameters"] = parameter_filter.filter(display_event['queryStringParameters'])
  display_event["pathParameters"] = parameter_filter.filter(display_event['pathParameters'])
  json_dump(display_event)
end

#json_dump(data) ⇒ Object

Handles binary data safely



133
134
135
136
137
138
# File 'lib/jets/controller/base.rb', line 133

def json_dump(data)
  JSON.dump(data)
rescue Encoding::UndefinedConversionError
  data['body'] = '[BINARY]'
  JSON.dump(data)
end

#log_finish(options = {}) ⇒ Object

Documented interface method, careful not to rename



113
114
115
116
# File 'lib/jets/controller/base.rb', line 113

def log_finish(options={})
  status, took = options[:status], options[:took]
  Jets.logger.info "Completed Status Code #{status} in #{took}s"
end

#log_startObject

Documented interface method, careful not to rename



103
104
105
106
107
108
109
110
# File 'lib/jets/controller/base.rb', line 103

def log_start
  # JSON.dump makes logging look pretty in CloudWatch logs because it keeps it on 1 line
  ip = request.ip
  Jets.logger.info "Started #{@event['httpMethod']} \"#{@event['path']}\" for #{ip} at #{Time.now}"
  Jets.logger.info "Processing #{self.class.name}##{@meth}"
  Jets.logger.info "  Event: #{event_log}"
  Jets.logger.info "  Parameters: #{JSON.dump(filtered_parameters.to_h)}"
end

#process!Object

One key difference between process! vs dispatch!

process! - takes the request through the middleware stack
dispatch! - does not

Most of the time, you want process! instead of dispatch!



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/jets/controller/base.rb', line 45

def process!
  adapter = Jets::Controller::Rack::Adapter.new(event, context, meth)
  adapter.rack_vars(
    'jets.controller' => self,
    'lambda.context' => context,
    'lambda.event' => event,
    'lambda.meth' => meth,
  )

  # adapter.process calls
  #
  #     Jets.application.call(env)
  #
  # and that goes through the middleware stacks. The last middleware stack is Jets::Controller::Middleware::Main
  #
  #     class Jets::Controller::Middleware::Main
  #       def call!
  #         setup
  #         @controller.dispatch! # Returns triplet
  #       end
  #     end
  #
  adapter.process # Returns API Gateway hash structure
end