RTIX / src /interfaces /http /cache.rs
github-actions
deploy: clean backend production release
d8ffec9
use axum::{
body::Body,
http::{header, Response},
response::IntoResponse,
};
// ─── Cache Policy Constants ───────────────────────────────────────────────────
/// Authenticated user data — never cache at CDN layer.
pub const CACHE_PRIVATE: &str = "private, no-store";
/// Short-lived public data (60s). Ideal for dashboard summaries and analytics.
/// `s-maxage` instructs CDN; `stale-while-revalidate` allows background refresh.
pub const CACHE_SHORT: &str = "public, max-age=60, s-maxage=60, stale-while-revalidate=30";
/// Medium-lived public data (5 min). For product listings and storefront pages.
pub const CACHE_MEDIUM: &str = "public, max-age=300, s-maxage=300, stale-while-revalidate=60";
/// Immutable long-lived content (24h). For static assets with content hashes.
pub const CACHE_LONG: &str = "public, max-age=86400, s-maxage=86400, immutable";
/// Always revalidate — for exports and reports that must be fresh.
pub const CACHE_REVALIDATE: &str = "public, max-age=0, must-revalidate";
// ─── Helpers ─────────────────────────────────────────────────────────────────
/// Inject `Cache-Control` and `Vary: Accept-Encoding` headers into any response.
pub fn with_cache<R: IntoResponse>(response: R, policy: &'static str) -> Response<Body> {
let mut res = response.into_response();
let headers = res.headers_mut();
headers.insert(
header::CACHE_CONTROL,
header::HeaderValue::from_static(policy),
);
headers.insert(
header::VARY,
header::HeaderValue::from_static("Accept-Encoding"),
);
res
}
/// Add ETag derived from a resource version/timestamp for conditional GETs.
pub fn with_etag<R: IntoResponse>(response: R, version: &str) -> Response<Body> {
let etag = format!("\"{}\"", version);
let mut res = response.into_response();
if let Ok(value) = header::HeaderValue::from_str(&etag) {
res.headers_mut().insert(header::ETAG, value);
}
res
}
/// Combine cache policy and ETag in one call.
pub fn with_cache_and_etag<R: IntoResponse>(
response: R,
policy: &'static str,
version: &str,
) -> Response<Body> {
let etag = format!("\"{}\"", version);
let mut res = response.into_response();
let headers = res.headers_mut();
headers.insert(
header::CACHE_CONTROL,
header::HeaderValue::from_static(policy),
);
headers.insert(
header::VARY,
header::HeaderValue::from_static("Accept-Encoding"),
);
if let Ok(value) = header::HeaderValue::from_str(&etag) {
headers.insert(header::ETAG, value);
}
res
}