armature_lambda/lib.rs
1//! # Armature Lambda
2//!
3//! AWS Lambda runtime adapter for Armature applications.
4//!
5//! This crate runs an HTTP handler on AWS Lambda behind API Gateway, ALB, or
6//! Lambda Function URLs, translating the incoming event into a
7//! [`LambdaRequest`] and the handler's [`LambdaResponse`] back out.
8//!
9//! ## What this crate does and does not do
10//!
11//! [`LambdaRuntime`] drives any type implementing [`RequestHandler`], which is
12//! stated in this crate's own [`LambdaRequest`]/[`LambdaResponse`] types. It
13//! does **not** convert to or from `armature_core::HttpRequest` /
14//! `HttpResponse`, and there is no blanket implementation for an Armature
15//! `Application` — wiring one up is the application author's job, most easily
16//! via `impl_lambda_handler!` (see its documentation for the exact shape it
17//! expects).
18//!
19//! ## Quick Start
20//!
21//! ```rust,ignore
22//! use armature_lambda::{LambdaRequest, LambdaResponse, LambdaRuntime};
23//!
24//! #[tokio::main]
25//! async fn main() -> Result<(), lambda_runtime::Error> {
26//! // Initialize tracing for CloudWatch
27//! armature_lambda::init_tracing();
28//!
29//! let handler = |req: LambdaRequest| async move {
30//! LambdaResponse::ok(format!("Hello from {}!", req.path))
31//! };
32//!
33//! LambdaRuntime::new(handler).run().await
34//! }
35//! ```
36//!
37//! ## Deployment
38//!
39//! Build for Lambda with:
40//!
41//! ```bash
42//! # Install cargo-lambda
43//! cargo install cargo-lambda
44//!
45//! # Build for Lambda
46//! cargo lambda build --release
47//!
48//! # Deploy
49//! cargo lambda deploy
50//! ```
51
52mod error;
53mod request;
54mod response;
55mod runtime;
56
57pub use error::{LambdaError, Result};
58pub use request::{LambdaRequest, RequestContext};
59pub use response::LambdaResponse;
60pub use runtime::{LambdaConfig, LambdaRuntime, RequestHandler};
61
62// Re-export lambda types
63pub use lambda_http;
64pub use lambda_runtime;
65
66// Re-exported so `impl_lambda_handler!` can name the attribute macro through
67// `$crate`. Without this the macro would only expand in crates that happen to
68// depend on `async-trait` themselves and under that exact name.
69pub use async_trait;
70
71/// Initialize tracing for Lambda/CloudWatch.
72///
73/// This sets up structured JSON logging suitable for CloudWatch Logs.
74pub fn init_tracing() {
75 use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
76
77 let filter = tracing_subscriber::EnvFilter::try_from_default_env()
78 .unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info"));
79
80 tracing_subscriber::registry()
81 .with(filter)
82 .with(tracing_subscriber::fmt::layer().json().flatten_event(true))
83 .init();
84}
85
86/// Initialize tracing with a custom log level.
87pub fn init_tracing_with_level(level: &str) {
88 use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
89
90 let filter = tracing_subscriber::EnvFilter::new(level);
91
92 tracing_subscriber::registry()
93 .with(filter)
94 .with(tracing_subscriber::fmt::layer().json().flatten_event(true))
95 .init();
96}