lambda_lw_http_router/lib.rs
1//! Lambda LightWeight HTTP Router (lambda-lw-http-router) is a lightweight routing library for AWS Lambda HTTP events.
2//!
3//! It provides a simple and efficient way to define routes and handlers for AWS Lambda functions
4//! that process HTTP events from API Gateway, Application Load Balancer, and WebSocket APIs.
5//!
6//! # Features
7//!
8//! * Support for multiple AWS event types (API Gateway v2, v1, ALB, WebSocket)
9//! * Path parameter extraction
10//! * Type-safe route handlers
11//! * Compile-time route registration
12//! * Minimal runtime overhead
13//!
14//! # Quick Start
15//!
16//! ```rust
17//! # use lambda_lw_http_router::{define_router, route};
18//! # use aws_lambda_events::apigw::ApiGatewayV2httpRequest;
19//! # use serde_json::{json, Value};
20//! # use lambda_runtime::Error;
21//! #
22//! // Define your application state
23//! #[derive(Clone)]
24//! struct AppState {
25//! // your state fields here
26//! }
27//!
28//! // Set up the router
29//! define_router!(event = ApiGatewayV2httpRequest, state = AppState);
30//!
31//! // Define a route handler
32//! #[route(path = "/hello/{name}")]
33//! async fn handle_hello(ctx: RouteContext) -> Result<Value, Error> {
34//! let name = ctx.params.get("name").map(|s| s.as_str()).unwrap_or("World");
35//! Ok(json!({
36//! "message": format!("Hello, {}!", name)
37//! }))
38//! }
39//!
40//! # fn main() {}
41//! ```
42//!
43//! # Examples
44//!
45//! Basic usage with default module name:
46//!
47//! ```rust
48//! # use lambda_lw_http_router::define_router;
49//! # use aws_lambda_events::apigw::ApiGatewayV2httpRequest;
50//! # use serde_json::{json, Value};
51//! # use lambda_runtime::Error;
52//! #
53//! #[derive(Clone)]
54//! struct AppState {
55//! // your state fields here
56//! }
57//!
58//! define_router!(event = ApiGatewayV2httpRequest, state = AppState);
59//!
60//! // This creates a module with the following types:
61//! // Router - Router<AppState, ApiGatewayV2httpRequest>
62//! // RouterBuilder - RouterBuilder<AppState, ApiGatewayV2httpRequest>
63//! // RouteContext - RouteContext<AppState, ApiGatewayV2httpRequest>
64//! # fn main() {}
65//! ```
66//!
67//! Custom module name for better readability or multiple routers:
68//!
69//! ```rust
70//! # use lambda_lw_http_router::define_router;
71//! # use aws_lambda_events::apigw::ApiGatewayV2httpRequest;
72//! # use aws_lambda_events::alb::AlbTargetGroupRequest;
73//! # use serde_json::{json, Value};
74//! # use lambda_runtime::Error;
75//! #
76//! #[derive(Clone)]
77//! struct AppState {
78//! // your state fields here
79//! }
80//!
81//! // Define an API Gateway router
82//! define_router!(event = ApiGatewayV2httpRequest, module = api_router, state = AppState);
83//!
84//! // Define an ALB router in the same application
85//! define_router!(event = AlbTargetGroupRequest, module = alb_router, state = AppState);
86//!
87//! // Now you can use specific types for each router:
88//! // api_router::Router
89//! // api_router::RouterBuilder
90//! // api_router::RouteContext
91//! //
92//! // alb_router::Router
93//! // alb_router::RouterBuilder
94//! // alb_router::RouteContext
95//! # fn main() {}
96//! ```
97//!
98//! # Usage with Route Handlers
99//!
100//! The module name defined here should match the `module` parameter in your route handlers:
101//!
102//! ```rust
103//! # use lambda_lw_http_router::{define_router, route};
104//! # use aws_lambda_events::apigw::ApiGatewayV2httpRequest;
105//! # use serde_json::{json, Value};
106//! # use lambda_runtime::Error;
107//! # #[derive(Clone)]
108//! # struct AppState { }
109//! #
110//! define_router!(event = ApiGatewayV2httpRequest, module = api_router, state = AppState);
111//!
112//! #[route(path = "/hello", module = "api_router")]
113//! async fn handle_hello(ctx: api_router::RouteContext) -> Result<Value, Error> {
114//! Ok(json!({ "message": "Hello, World!" }))
115//! }
116//! # fn main() {}
117//! ```
118
119pub use lambda_lw_http_router_core::*;
120pub use lambda_lw_http_router_macro::route;
121
122/// Defines a router module with the necessary type aliases for your Lambda application.
123///
124/// This macro creates a module containing type aliases for the router components,
125/// making them easily accessible throughout your application. It's typically used
126/// at the beginning of your Lambda function to set up the routing infrastructure.
127///
128/// # Type Aliases
129///
130/// The macro creates the following type aliases:
131/// * `Event` - The Lambda HTTP event type (e.g., ApiGatewayV2httpRequest)
132/// * `Router` - The router instance type for your application
133/// * `RouterBuilder` - The builder type for constructing routers
134/// * `RouteContext` - The context type passed to route handlers
135///
136/// # Arguments
137///
138/// * `event` - The Lambda HTTP event type (required). Supported types:
139/// * `ApiGatewayV2httpRequest` - API Gateway HTTP API v2
140/// * `ApiGatewayProxyRequest` - API Gateway REST API v1
141/// * `AlbTargetGroupRequest` - Application Load Balancer
142/// * `ApiGatewayWebsocketProxyRequest` - API Gateway WebSocket
143/// * `module` - The module name (optional, defaults to an internal name)
144/// * `state` - The state type for the router
145///
146/// # Examples
147///
148/// Basic usage with default module name:
149/// ```rust,no_run
150/// use lambda_lw_http_router::define_router;
151/// use aws_lambda_events::apigw::ApiGatewayV2httpRequest;
152/// use serde_json::{json, Value};
153/// use lambda_runtime::Error;
154///
155/// // Define your application state
156/// #[derive(Clone)]
157/// struct AppState {
158/// // your state fields here
159/// }
160///
161/// define_router!(event = ApiGatewayV2httpRequest, state = AppState);
162///
163/// // This creates a module with the following types:
164/// // Router - Router<AppState, ApiGatewayV2httpRequest>
165/// // RouterBuilder - RouterBuilder<AppState, ApiGatewayV2httpRequest>
166/// // RouteContext - RouteContext<AppState, ApiGatewayV2httpRequest>
167/// # fn main() {}
168/// ```
169///
170/// Custom module name for better readability or multiple routers:
171/// ```rust,no_run
172/// use lambda_lw_http_router::define_router;
173/// use aws_lambda_events::apigw::ApiGatewayV2httpRequest;
174/// use aws_lambda_events::alb::AlbTargetGroupRequest;
175/// use serde_json::{json, Value};
176/// use lambda_runtime::Error;
177///
178/// // Define your application state
179/// #[derive(Clone)]
180/// struct AppState {
181/// // your state fields here
182/// }
183///
184/// // Define an API Gateway router
185/// define_router!(event = ApiGatewayV2httpRequest, module = api_router, state = AppState);
186///
187/// // Define an ALB router in the same application
188/// define_router!(event = AlbTargetGroupRequest, module = alb_router, state = AppState);
189///
190/// // Now you can use specific types for each router:
191/// // api_router::Router
192/// // api_router::RouterBuilder
193/// // api_router::RouteContext
194/// //
195/// // alb_router::Router
196/// // alb_router::RouterBuilder
197/// // alb_router::RouteContext
198/// # fn main() {}
199/// ```
200///
201/// # Usage with Route Handlers
202///
203/// The module name defined here should match the `module` parameter in your route handlers:
204///
205/// ```rust, no_run
206/// use lambda_lw_http_router::{define_router, route};
207/// use aws_lambda_events::apigw::ApiGatewayV2httpRequest;
208/// use serde_json::{json, Value};
209/// use lambda_runtime::Error;
210///
211/// // Define your application state
212/// #[derive(Clone)]
213/// struct AppState {
214/// // your state fields here
215/// }
216///
217/// define_router!(event = ApiGatewayV2httpRequest, module = api_router, state = AppState);
218///
219/// #[route(path = "/hello", module = "api_router")]
220/// async fn handle_hello(ctx: api_router::RouteContext) -> Result<Value, Error> {
221/// let name = ctx.params.get("name").map(|s| s.as_str()).unwrap_or("World");
222/// Ok(json!({ "message": format!("Hello, {}!", name) }))
223/// }
224/// # fn main() {}
225/// ```
226#[macro_export]
227macro_rules! define_router {
228 (event = $event_type:ty, module = $module:ident, state = $state_type:ty) => {
229 pub mod $module {
230 use super::*;
231
232 pub type Event = $event_type;
233 pub type State = $state_type;
234 pub type Router = ::lambda_lw_http_router::Router<State, Event>;
235 pub type RouterBuilder = ::lambda_lw_http_router::RouterBuilder<State, Event>;
236 pub type RouteContext = ::lambda_lw_http_router::RouteContext<State, Event>;
237 }
238 pub use $module::*;
239 };
240
241 (event = $event_type:ty, state = $state_type:ty) => {
242 mod __lambda_lw_http_router_core_default_router {
243 use super::*;
244
245 pub type Event = $event_type;
246 pub type State = $state_type;
247 pub type Router = ::lambda_lw_http_router::Router<State, Event>;
248 pub type RouterBuilder = ::lambda_lw_http_router::RouterBuilder<State, Event>;
249 pub type RouteContext = ::lambda_lw_http_router::RouteContext<State, Event>;
250 }
251 pub use __lambda_lw_http_router_core_default_router::*;
252 };
253}
254
255#[cfg(doctest)]
256extern crate doc_comment;
257
258#[cfg(doctest)]
259use doc_comment::doctest;
260
261#[cfg(doctest)]
262doctest!("../README.md", readme);