Lambda Handler
Belt::LambdaHandler is the module you include in your Lambda entry point.
It provides the lambda_handler method that AWS Lambda invokes, wrapping
your application logic with observability, CORS, and error handling.
Basic Usage
require "belt"
include Belt::LambdaHandler
ROUTER = Belt::ActionRouter.new(routes: Routes::API, gateway: "api")
def execute(path:, body:, event:)
ROUTER.route(event: event, body: body)
end
What It Does
When a request arrives, lambda_handler automatically:
- Initializes observability — structured logging + CloudWatch metrics
- Handles OPTIONS preflight — returns CORS headers immediately
- Parses the request body — JSON string → Ruby hash
- Calls your
executemethod — withpath:,body:, andevent: - Catches unhandled errors — returns a CORS-enabled error response
- Emits metrics — request count, latency, error count via EMF
The execute Method
You must define execute in your Lambda file. It receives:
| Param | Description |
|---|---|
path: |
The request path (e.g., /posts/123) |
body: |
Parsed request body (Hash or nil) |
event: |
Full API Gateway event (for headers, query params, auth context) |
Return value should be a response hash: { statusCode:, headers:, body: }.
Typically you just call ROUTER.route(...) which returns the correct format.
Multiple Lambdas
If your app has multiple Lambda functions (via function in routes):
# lambda/worker.rb
require "belt"
include Belt::LambdaHandler
ROUTER = Belt::ActionRouter.new(routes: Routes::WORKER, gateway: "worker")
def execute(path:, body:, event:)
ROUTER.route(event: event, body: body)
end
Each Lambda entry point gets its own route manifest and gateway name.
Configuration
Configure via config/lambda/<name>.yml:
handler: lambda/api.lambda_handler
runtime: ruby3.3
timeout: 30
memory: 256
layers:
- ${var.ruby_layer_arn}
environment:
ENVIRONMENT: ${var.environment}
APP_NAME: my-app
ERROR_NOTIFICATION_TOPIC_ARN: ${var.sns_topic_arn}
Observability
The handler sets up Belt::Observability::Logger and Belt::Observability::Metrics
automatically. Use them anywhere in your app:
Belt::Observability::Logger.info("Order created", order_id: order.id)
Belt::Observability::Metrics.track_event("OrderCreated", model: "Order")
Environment Variables
| Variable | Purpose |
|---|---|
ENVIRONMENT |
Controls error verbosity (dev*, local, test = verbose) |
BELT_METRICS_NAMESPACE |
CloudWatch namespace (default: Belt) |
ACTION |
Service name for logging |
ERROR_NOTIFICATION_TOPIC_ARN |
SNS topic for error alerts |
CORS_ALLOWED_ORIGINS |
Comma-separated allowed origins |
See Also
belt explain routing— how ActionRouter dispatches requestsbelt explain controllers— how dispatched requests are handledbelt explain deployment— Lambda packaging and configuration