rust 59 lines · 8 steps

Flash messages via Axum middleware

A shared queue collects flash messages during a request, then serializes them into a cookie on the way out.

Explained by highlit
1use axum::{
2 body::Body,
3 extract::Request,
4 http::{header::SET_COOKIE, HeaderValue},
5 middleware::Next,
6 response::Response,
7};
8use std::sync::{Arc, Mutex};
9 
10#[derive(Clone, Default)]
11pub struct FlashQueue(Arc<Mutex<Vec<Flash>>>);
12 
13#[derive(Clone)]
14pub struct Flash {
15 pub level: &'static str,
16 pub message: String,
17}
18 
19impl FlashQueue {
20 pub fn push(&self, level: &'static str, message: impl Into<String>) {
21 self.0.lock().unwrap().push(Flash { level, message: message.into() });
22 }
23 
24 fn drain(&self) -> Vec<Flash> {
25 std::mem::take(&mut *self.0.lock().unwrap())
26 }
27}
28 
29pub async fn flash_middleware(mut req: Request, next: Next) -> Response {
30 let queue = FlashQueue::default();
31 req.extensions_mut().insert(queue.clone());
32 
33 let mut res = next.run(req).await;
34 
35 let messages = queue.drain();
36 if messages.is_empty() {
37 return res;
38 }
39 
40 let encoded: Vec<String> = messages
41 .into_iter()
42 .map(|f| format!("{}:{}", f.level, urlencoding::encode(&f.message)))
43 .collect();
44 
45 let cookie = format!(
46 "flash={}; Path=/; HttpOnly; SameSite=Lax; Max-Age=30",
47 urlencoding::encode(&encoded.join("|"))
48 );
49 
50 if let Ok(value) = HeaderValue::from_str(&cookie) {
51 res.headers_mut().insert(SET_COOKIE, value);
52 }
53 
54 res
55}
56 
57async fn _bind() -> Body {
58 Body::empty()
59}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Request extensions let middleware hand a shared, mutable object to downstream handlers without global state.
  2. 2Wrapping state in Arc<Mutex<...>> makes it Clone-able and thread-safe while keeping a single underlying buffer.
  3. 3Draining collected state after the handler runs is a clean place to translate it into response side effects.

Related explainers

Share this explainer

Here's the card — post it anywhere.

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