Cache
Middleware that provides caching functionality.
Cache middleware can provide caching function for StatusCode
, Headers
, Body
in Response
. For the content that has been cached, when processing the request next time, Cache middleware will directly send the content cached in memory to the client.
Note that this plugin will not cache Response
whose Body
is a ResBody::Stream
. If applied to a Response
of this type, the Cache will not process these requests and will not cause error.
Main Features
CacheIssuer
provides an abstraction over the assigned cache keys.RequestIssuer
is an implementation of it that defines which parts of the requested URL and the requestedMethod
to generate a cache key. You can also define your own The logic of cache key generation. The cache key does not have to be a string type, any type that satisfies the constraints ofHash + Eq + Send + Sync + 'static
can be used as a key.CacheStore
provides access to data.MokaStore
is a built-inmoka
-based memory cache implementation. You can also define your own implementation.Cache
is a structure that implementsHandler
, and there is askipper
field inside, which can be specified to skip certain requests that do not need to be cached. By default,MethodSkipper
will be used to skip all request exceptMethod::GET
.Internal implementation sample code:
impl<S, I> Cache<S, I> { pub fn new(store: S, issuer: I) -> Self { let skipper = MethodSkipper::new().skip_all().skip_get(false); Cache { store, issuer, skipper: Box::new(skipper), } } }
Example
use std::time::Duration;
use salvo::cache::{Cache, MokaStore, RequestIssuer};
use salvo::prelude::*;
use salvo::writing::Text;
use time::OffsetDateTime;
#[handler]
async fn home() -> Text<&'static str> {
Text::Html(HOME_HTML)
}
#[handler]
async fn short() -> String {
format!(
"Hello World, my birth time is {}",
OffsetDateTime::now_utc()
)
}
#[handler]
async fn long() -> String {
format!(
"Hello World, my birth time is {}",
OffsetDateTime::now_utc()
)
}
#[tokio::main]
async fn main() {
tracing_subscriber::fmt().init();
let short_cache = Cache::new(
MokaStore::builder()
.time_to_live(Duration::from_secs(5))
.build(),
RequestIssuer::default(),
);
let long_cache = Cache::new(
MokaStore::builder()
.time_to_live(Duration::from_secs(60))
.build(),
RequestIssuer::default(),
);
let router = Router::new()
.get(home)
.push(Router::with_path("short").hoop(short_cache).get(short))
.push(Router::with_path("long").hoop(long_cache).get(long));
let acceptor = TcpListener::new("127.0.0.1:5800").bind().await;
Server::new(acceptor).serve(router).await;
}
static HOME_HTML: &str = r#"
<!DOCTYPE html>
<html>
<head>
<title>Cache Example</title>
</head>
<body>
<h2>Cache Example</h2>
<p>
This examples shows how to use cache middleware.
</p>
<p>
<a href="/short" target="_blank">Cache 5 seconds</a>
</p>
<p>
<a href="/long" target="_blank">Cache 1 minute</a>
</p>
</body>
</html>
"#;
[package]
name = "example-cache-simple"
version = "0.1.0"
edition = "2021"
publish = false
[dependencies]
salvo = {workspace = true, features = ["cache"] }
tokio = { version = "1", features = ["macros"] }
time = "0.3"
tracing = "0.1"
tracing-subscriber = "0.3"