Skip to content

Commit a09d1b5

Browse files
committed
cleanup main api file
1 parent 2b69231 commit a09d1b5

File tree

1 file changed

+17
-63
lines changed

1 file changed

+17
-63
lines changed

lib/hooks/app/api.rb

Lines changed: 17 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@
1010
require_relative "../core/logger_factory"
1111
require_relative "../core/log"
1212

13-
# import all core endpoint classes dynamically
14-
Dir[File.join(__dir__, "endpoints/**/*.rb")].sort.each do |file|
15-
require file
16-
end
13+
# Import all core endpoint classes dynamically
14+
Dir[File.join(__dir__, "endpoints/**/*.rb")].sort.each { |file| require file }
1715

1816
module Hooks
1917
module App
@@ -22,58 +20,37 @@ class API
2220
include Hooks::App::Helpers
2321
include Hooks::App::Auth
2422

25-
# Expose start_time for endpoint modules
26-
def self.start_time
27-
@start_time
23+
class << self
24+
attr_reader :start_time
2825
end
2926

3027
# Create a new configured API class
3128
def self.create(config:, endpoints:, log:)
32-
# Store startup time for uptime calculation
3329
@start_time = Time.now
3430

35-
# Capture values in local variables for closure
36-
captured_config = config
37-
captured_endpoints = endpoints
38-
captured_logger = log
39-
40-
# Set global logger instance for plugins/validators
4131
Hooks::Log.instance = log
4232

43-
# Create the API class with dynamic routes
4433
api_class = Class.new(Grape::API) do
45-
# Accept all content types but don't auto-parse
4634
content_type :json, "application/json"
4735
content_type :txt, "text/plain"
4836
content_type :xml, "application/xml"
4937
content_type :any, "*/*"
50-
format :txt # Use text format so no automatic parsing happens
38+
format :txt
5139
default_format :txt
5240
end
5341

54-
# Use class_eval to dynamically define routes
5542
api_class.class_eval do
56-
# Define helper methods first, before routes
5743
helpers Helpers, Auth
5844

59-
# Mount core operational endpoints
6045
mount Hooks::App::HealthEndpoint => config[:health_path]
6146
mount Hooks::App::VersionEndpoint => config[:version_path]
6247

63-
# Define webhook endpoints dynamically
64-
captured_endpoints.each do |endpoint_config|
65-
full_path = "#{captured_config[:root_path]}#{endpoint_config[:path]}"
48+
endpoints.each do |endpoint_config|
49+
full_path = "#{config[:root_path]}#{endpoint_config[:path]}"
6650
handler_class_name = endpoint_config[:handler]
6751

68-
# Use send to dynamically create POST route
69-
send(:post, full_path) do
52+
post(full_path) do
7053
request_id = uuid
71-
72-
# Use captured values
73-
config = captured_config
74-
log = captured_logger
75-
76-
# Set request context for logging
7754
request_context = {
7855
request_id:,
7956
path: full_path,
@@ -82,57 +59,37 @@ def self.create(config:, endpoints:, log:)
8259

8360
Core::LogContext.with(request_context) do
8461
begin
85-
# Enforce request limits
8662
enforce_request_limits(config)
87-
88-
# Get raw body for signature validation
8963
request.body.rewind
9064
raw_body = request.body.read
9165

92-
# Verify/validate request if configured
9366
if endpoint_config[:auth]
9467
log.info "validating request (id: #{request_id}, handler: #{handler_class_name})"
95-
validate_auth!(raw_body, headers, endpoint_config) if endpoint_config[:auth]
68+
validate_auth!(raw_body, headers, endpoint_config)
9669
end
9770

98-
# Parse payload (symbolize_payload is true by default)
9971
payload = parse_payload(raw_body, headers, symbolize: config[:symbolize_payload])
100-
101-
# Load and instantiate handler
10272
handler = load_handler(handler_class_name, config[:handler_dir])
73+
normalized_headers = config[:normalize_headers] ? Hooks::Utils::Normalize.headers(headers) : headers
10374

104-
# Normalize the headers based on the endpoint configuration (normalization is the default)
105-
headers = Hooks::Utils::Normalize.headers(headers) if config[:normalize_headers]
106-
107-
# Call handler
10875
response = handler.call(
10976
payload:,
110-
headers:,
77+
headers: normalized_headers,
11178
config: endpoint_config
11279
)
11380

11481
log.info "request processed successfully (id: #{request_id}, handler: #{handler_class_name})"
115-
116-
# Return response as JSON string when using txt format
117-
status 200 # Explicitly set status to 200
82+
status 200
11883
content_type "application/json"
11984
(response || { status: "ok" }).to_json
120-
12185
rescue => e
12286
log.error "request failed: #{e.message} (id: #{request_id}, handler: #{handler_class_name})"
123-
124-
# Return error response
12587
error_response = {
12688
error: e.message,
12789
code: determine_error_code(e),
128-
request_id:
90+
request_id: request_id
12991
}
130-
131-
# Add backtrace in all environments except production
132-
unless config[:production] == true
133-
error_response[:backtrace] = e.backtrace
134-
end
135-
92+
error_response[:backtrace] = e.backtrace unless config[:production]
13693
status error_response[:code]
13794
content_type "application/json"
13895
error_response.to_json
@@ -141,16 +98,13 @@ def self.create(config:, endpoints:, log:)
14198
end
14299
end
143100

144-
# Catch-all route for unknown endpoints - use default handler
145-
# Only create if explicitly enabled in config
146-
if captured_config[:use_catchall_route]
147-
route_path = Hooks::App::CatchallEndpoint.mount_path(captured_config)
148-
route_block = Hooks::App::CatchallEndpoint.route_block(captured_config, captured_logger)
101+
if config[:use_catchall_route]
102+
route_path = Hooks::App::CatchallEndpoint.mount_path(config)
103+
route_block = Hooks::App::CatchallEndpoint.route_block(config, log)
149104
post(route_path, &route_block)
150105
end
151106
end
152107

153-
# Return the configured API class
154108
api_class
155109
end
156110
end

0 commit comments

Comments
 (0)