Class: Belt::ActionRouter

Inherits:
Object
  • Object
show all
Defined in:
lib/belt/action_router.rb

Overview

Routes incoming requests to controllers based on a route manifest.

Usage:

ROUTER = Belt::ActionRouter.new(routes: MY_ROUTES, namespace: "api")
response = ROUTER.route(event: event, body: body)

Defined Under Namespace

Classes: RouteNotFound

Instance Method Summary collapse

Constructor Details

#initialize(routes:, namespace:) ⇒ ActionRouter

Returns a new instance of ActionRouter.



16
17
18
19
20
# File 'lib/belt/action_router.rb', line 16

def initialize(routes:, namespace:)
  @namespace = namespace.to_s
  @namespace_module_name = "#{@namespace.split('_').map(&:capitalize).join}Controllers"
  @routes = build_route_table(routes)
end

Instance Method Details

#extract_path_params(pattern, actual_path) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
# File 'lib/belt/action_router.rb', line 45

def extract_path_params(pattern, actual_path)
  pattern_segments = pattern.split('/')
  path_segments = actual_path.split('/')
  params = {}

  pattern_segments.each_with_index do |seg, i|
    params[seg[1..-2]] = path_segments[i] if seg.start_with?('{') && seg.end_with?('}')
  end

  params
end

#find_route(method, path) ⇒ Object



40
41
42
43
# File 'lib/belt/action_router.rb', line 40

def find_route(method, path)
  path_segments = path.split('/')
  @routes.find { |r| r[:verb] == method && segments_match?(r[:segments], path_segments) }
end

#route(event:, body:) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/belt/action_router.rb', line 22

def route(event:, body:)
  method = event['httpMethod']
  full_path = event['path']
  match_path = strip_namespace_prefix(full_path)

  route_info = find_route(method, match_path)

  unless route_info
    Belt::Observability::Logger.instance&.warn('Route not found', method: method, path: full_path)
    return error_response('Not found', 404, event)
  end

  path_params = extract_path_params(route_info[:pattern], match_path)
  event['pathParameters'] = (event['pathParameters'] || {}).merge(path_params)

  dispatch_to_controller(route_info, event, body)
end