Depot

Depot is used to save data when process current request. It is useful for middlewares to share data.

A depot instance is created when server get a request from client. The depot will be dropped when all process for this request done.

For example, we can set current_user in set_user, and then use this value in the following middlewares and handlers.

use salvo::prelude::*;

#[handler]
async fn set_user(depot: &mut Depot) {
    depot.insert("current_user", "Elon Musk");
}
#[handler]
async fn hello(depot: &mut Depot) -> String {
    // Notice: Don't use String here, because you inserted a &str.
    let user = depot.get::<&str>("current_user").copied().unwrap();
    format!("Hey {}, I love your money and girls!", user)
}

#[tokio::main]
async fn main() {
    tracing_subscriber::fmt().init();

    let router = Router::new().hoop(set_user).goal(hello);

    let acceptor = TcpListener::new("127.0.0.1:5800").bind().await;
    Server::new(acceptor).serve(router).await;
}
[package]
name = "example-use-depot"
version = "0.1.0"
edition = "2021"
publish = false

[dependencies]
salvo.workspace = true
tokio = { version = "1", features = ["macros"] }
tracing = "0.1"
tracing-subscriber = "0.3"

Set and retrieve data via insert and get

As shown above, key and value can be inserted into Depot via insert. For values of this type, get can be used to retrieve them directly.

depot.insert("a", "b");
assert_eq!(depot.get::<&str>("a").copied().unwrap(), "b")

Returns None if the key does not exist, or if the key exists, but the types do not match.

Set and retrieve data via inject and obtain

Sometimes, there are cases where you don't need a relation-specific key, and there is also a unique instance of that type. You can use inject to inject data, and obtain to get data out. They don't require you to provide a key.

depot.inject(Config::new());
depot.obtain::<Config>();