| Crates.io | aws-lambda-router |
| lib.rs | aws-lambda-router |
| version | 0.1.1 |
| created_at | 2025-11-29 21:36:41.956158+00 |
| updated_at | 2025-11-29 21:50:38.579618+00 |
| description | A lightweight, Express-like REST API routing framework for AWS Lambda with middleware, authentication, and CORS support |
| homepage | https://github.com/Rehan712/lambda-router |
| repository | https://github.com/Rehan712/lambda-router |
| max_upload_size | |
| id | 1957515 |
| size | 86,216 |
A lightweight, Express-like REST API routing framework for AWS Lambda functions with support for middleware, authentication, and CORS.
:userId, :id)Add this to your Cargo.toml:
[dependencies]
aws-lambda-router = "0.1"
lambda_runtime = "0.8"
tokio = { version = "1.0", features = ["rt", "macros"] }
serde_json = "1.0"
use aws_lambda_router::{Router, Request, Response, Context};
use lambda_runtime::Error;
use serde_json::json;
async fn get_user(req: Request, _ctx: Context) -> Result<Response, Error> {
let user_id = req.path_param("userId").unwrap_or_default();
Ok(Response::ok(json!({
"userId": user_id,
"name": "John Doe"
})))
}
async fn create_user(req: Request, _ctx: Context) -> Result<Response, Error> {
let body = req.json_body::<serde_json::Value>()?;
Ok(Response::created(json!({
"message": "User created",
"data": body
})))
}
async fn list_users(_req: Request, _ctx: Context) -> Result<Response, Error> {
Ok(Response::ok(json!({
"users": []
})))
}
#[tokio::main]
async fn main() -> Result<(), Error> {
let mut router = Router::new();
// Define routes
router.get("/api/users", list_users);
router.get("/api/users/:userId", get_user);
router.post("/api/users", create_user);
// Run the Lambda
lambda_runtime::run(router.into_service()).await
}
router.get("/path", handler);
router.post("/path", handler);
router.put("/path", handler);
router.delete("/path", handler);
router.patch("/path", handler);
router.options("/path", handler);
Use :paramName syntax to define path parameters:
router.get("/users/:userId", handler);
router.get("/users/:userId/posts/:postId", handler);
async fn handler(req: Request, _ctx: Context) -> Result<Response, Error> {
let user_id = req.path_param("userId").unwrap();
let post_id = req.path_param("postId").unwrap();
// ...
}
async fn handler(req: Request, ctx: Context) -> Result<Response, Error> {
// Path parameters
let id = req.path_param("id").unwrap_or_default();
// Query parameters
let page = req.query_param("page").unwrap_or("1".to_string());
// Headers
let auth = req.header("Authorization").unwrap_or_default();
// JSON body
let body: MyStruct = req.json_body()?;
// Raw body
let raw = req.body();
Ok(Response::ok(json!({})))
}
// Success responses
Response::ok(json!({"message": "Success"})) // 200
Response::created(json!({"id": "123"})) // 201
Response::no_content() // 204
// Error responses
Response::bad_request("Invalid input") // 400
Response::unauthorized("Invalid token") // 401
Response::forbidden("Access denied") // 403
Response::not_found("Resource not found") // 404
Response::internal_error("Something went wrong") // 500
// Custom status
Response::new(418, json!({"message": "I'm a teapot"}))
// With headers
Response::ok(json!({}))
.with_header("X-Custom-Header", "value")
CORS is automatically handled. Configure it as needed:
use aws_lambda_router::CorsConfig;
let cors = CorsConfig::new()
.allow_origin("https://example.com")
.allow_methods(vec!["GET", "POST", "PUT", "DELETE"])
.allow_headers(vec!["Content-Type", "Authorization"]);
use aws_lambda_router::{Middleware, Request, Response, Context, Next};
use async_trait::async_trait;
struct LoggingMiddleware;
#[async_trait]
impl Middleware for LoggingMiddleware {
async fn handle(&self, req: Request, ctx: Context, next: Next<'_>) -> Result<Response, Error> {
println!("Request: {} {}", req.method(), req.path());
let response = next.run(req, ctx).await?;
println!("Response: {}", response.status_code());
Ok(response)
}
}
// Add middleware to router
router.use_middleware(LoggingMiddleware);
The router provides structured error handling:
use aws_lambda_router::{RouterError, Result};
async fn handler(req: Request, _ctx: Context) -> Result<Response> {
let body: MyStruct = req.json_body()
.map_err(|_| RouterError::BadRequest("Invalid JSON".to_string()))?;
// Your logic here...
Ok(Response::ok(json!({})))
}
See the examples directory for complete working examples.
[package]
name = "my-lambda"
version = "0.1.0"
edition = "2021"
[dependencies]
aws-lambda-router = "0.1"
lambda_runtime = "0.8"
tokio = { version = "1.0", features = ["rt", "macros"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
[profile.release]
opt-level = "z"
lto = true
codegen-units = 1
panic = "abort"
strip = true
# Install cross-compilation target
rustup target add x86_64-unknown-linux-musl
# Build for Lambda
cargo build --release --target x86_64-unknown-linux-musl
# Package for deployment
cp target/x86_64-unknown-linux-musl/release/my-lambda bootstrap
zip lambda.zip bootstrap
This project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.