rust 38 lines · 7 steps

Request ID middleware in Axum

An Axum middleware that reuses or mints an X-Request-ID and threads it through the request and response.

Explained by highlit
1use axum::{
2 body::Body,
3 extract::Request,
4 http::{header::HeaderValue, HeaderName},
5 middleware::Next,
6 response::Response,
7};
8use uuid::Uuid;
9 
10static REQUEST_ID: HeaderName = HeaderName::from_static("x-request-id");
11 
12#[derive(Clone, Debug)]
13pub struct RequestId(pub String);
14 
15pub async fn propagate_request_id(mut request: Request<Body>, next: Next) -> Response {
16 let request_id = request
17 .headers()
18 .get(&REQUEST_ID)
19 .and_then(|value| value.to_str().ok())
20 .map(str::to_owned)
21 .unwrap_or_else(|| Uuid::new_v4().to_string());
22 
23 request
24 .extensions_mut()
25 .insert(RequestId(request_id.clone()));
26 
27 if let Ok(header_value) = HeaderValue::from_str(&request_id) {
28 request.headers_mut().insert(REQUEST_ID.clone(), header_value.clone());
29 
30 let mut response = next.run(request).await;
31 response
32 .headers_mut()
33 .insert(REQUEST_ID.clone(), header_value);
34 return response;
35 }
36 
37 next.run(request).await
38}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Reusing an inbound request ID when present preserves trace continuity across services.
  2. 2Request extensions let middleware hand typed data to downstream handlers without touching headers.
  3. 3Echoing the ID onto the response lets clients correlate their call with your logs.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Request ID middleware in Axum — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code