Use Axum and LambdaRequest (and context) at the same time #634
|
Hi! I am new to Rust. I've been writing Lambda in Python for a long time now, but I'm interested in writing this in Rust. I used to output the whole log first every time Lambda was started. like this:. I first wrote the following code to achieve something similar to this and it worked. main.rs async fn lambda_handler(request: Request) -> Result<Response<Body>, Error> {
let context = request.lambda_context();
lambda::log_incoming_event(&request, context);
// do something...
}
#[tokio::main]
async fn main() -> Result<(), Error> {
run(lambda::init_app(lambda_handler)).await
}utils/lambda.rs pub fn init_app<H, F>(lambda_handler: H) -> Cors<ServiceFn<H>>
where
H: Fn(Request) -> F,
F: Future<Output = Result<Response<Body>, LambdaError>>,
{
let level = env::var("LOG_LEVEL").unwrap_or_else(|_| "debug".to_string());
let level = Level::from_str(&level).unwrap();
tracing_subscriber::fmt()
.with_max_level(level)
.with_file(true)
.with_line_number(true)
.json()
.init();
let cors_layer = CorsLayer::new()
.allow_origin(
env::var("API_ALLOW_ORIGIN")
.expect("\"API_ALLOW_ORIGIN\" env var is not set.")
.parse::<HeaderValue>()
.unwrap(),
)
.allow_headers(vec![
header::AUTHORIZATION,
"Cognito-Auth-Header".parse::<HeaderName>().unwrap(),
header::CONTENT_TYPE,
"X-Amz-Date".parse::<HeaderName>().unwrap(),
"X-Amz-Security-Token".parse::<HeaderName>().unwrap(),
"X-Api-Key".parse::<HeaderName>().unwrap(),
])
.allow_methods(vec![
Method::POST,
Method::GET,
Method::PUT,
Method::PATCH,
Method::DELETE,
Method::OPTIONS,
]);
lambda_http::tower::ServiceBuilder::new()
.layer(cors_layer)
.service(service_fn(lambda_handler))
}
pub fn log_incoming_event(request: &Request, context: Context) {
if let RequestContext::ApiGatewayV1(request_context) = request.request_context() {
info!(
request_id = %context.request_id,
request_time = %request_context.request_time.unwrap_or_else(|| "No request time".to_string()),
http_version = ?request.version(),
method = ?request.method(),
resource_path = %request_context.resource_path.unwrap_or_else(|| "No resource path".to_string()),
fullpath = %request.uri(),
// Omitted...
authorizer = ?request_context.authorizer, // Structuring?
log_stream = %context.env_config.log_stream,
log_group = %context.env_config.log_group,
xray_trace_id = %context.xray_trace_id.unwrap_or_else(|| "None".to_string()),
client_context = ?context.client_context,
invoked_function_arn = %context.invoked_function_arn,
function_name = %context.env_config.function_name,
version = %context.env_config.version,
memory = ?context.env_config.memory,
deadline = ?context.deadline,
"Lambda incoming event:",
);
}
}
}However, after this, I wanted to use Axum for API routing, but I couldn't figure out how to use Axum's route object together with the How can I create an API routing for Axum while running a function to log all Lambda requests? |
Replies: 1 comment
|
the http variant of the runtime hides the lambda event from the developer, that's kind of what it's intended to do. instead of receiving a lambda request, you receive an does that help? does one of those options sound like it'll work for you? |
the http variant of the runtime hides the lambda event from the developer, that's kind of what it's intended to do. instead of receiving a lambda request, you receive an
http::Request, which is normally what code written with a more traditional web server framework expects. so you've got two choices here - either you log what you need out of the passed-inhttp::Request, or you dip down into the lower level (non-http) runtime and do the translation to anhttp::Requestyourself after logging, if that's the type you ultimately need.does that help? does one of those options sound like it'll work for you?