module AwsApiGatewayEventHandler
Constants
- NUMBER_REGEX
Public Instance Methods
call(event:, context:)
click to toggle source
# File lib/modulator/lambda_handler.rb, line 19 def call(event:, context:) wrapper_params = {} if ENV['wrapper_name'] # module init require Pathname.getwd.join(ENV['wrapper_path']).to_s wrapper = Object.const_get(ENV['wrapper_name']) mod_method = ENV['wrapper_method'] # check arity if wrapper.method(mod_method).parameters != [[:keyreq, :event], [:keyreq, :context]] raise("#{wrapper}.#{mod_method} should accept event and context keyword arguments") end # print call info puts "Calling wrapper #{wrapper}.#{mod_method}" wrapper_result = wrapper.send(mod_method, event: event, context: context) if wrapper_result.is_a?(Hash) # block with custom status and body return { statusCode: wrapper_result[:status], body: JSON.generate(wrapper_result[:body]) } if wrapper_result[:status] # or set params wrapper_params = wrapper_result elsif !wrapper_result # block if result is false/nil return { statusCode: 403, body: JSON.generate(forbidden: "#{wrapper}.#{mod_method}") } if !wrapper_result end end # module init require Pathname.getwd.join(ENV['module_path']).to_s mod = Object.const_get(ENV['module_name']) mod_method = ENV['module_method'] # gateway def verb = ENV['gateway_verb'] path = ENV['gateway_path'] # print call info method_signature = mod.method(mod_method).parameters puts "Resolving #{verb.to_s.upcase} #{path} to #{mod}.#{mod_method} with #{method_signature}" # cast path parameters to numbers path_params = event['pathParameters'].each_with_object({}) do |(key, value), params| if matcher = NUMBER_REGEX.match(value) value = matcher[1] ? Float(value) : value.to_i end params[key] = value end # merge wrapper params path_params.merge!(wrapper_params) # call the module method result = if ['GET', 'DELETE'].include?(verb) mod.send(mod_method, *path_params.values) elsif verb == 'POST' payload = JSON.parse(event['body'], symbolize_names: true) method_signature.each do |arg_type, arg_name| # [[:req, :id], [:key, :pet]] payload = {arg_name => payload} if arg_type == :key # scope payload to first named argument end # we can override GET to POST without payload, ruby will break if **payload is resolved from {} if payload.any? mod.send(mod_method, *path_params.values, **payload) else mod.send(mod_method, *path_params.values) end else raise 'Verb should be GET, POST or DELETE' end # set status and body values if result.nil? status = 404 body = nil # it will print json null string else status = result[:status] ? result[:status] : 200 body = result[:body] ? result[:body] : result end # return result return {statusCode: status, body: JSON.generate(body)} # print and return error rescue => e puts output = { statusCode: 500, body: JSON.generate( error: { class: e.class, message: e.message }.merge(ENV['debug'] ? {backtrace: e.backtrace.take(20)} : {}) ) } output end