Depot

Depot viene utilizzato per memorizzare dati temporanei coinvolti in una singola richiesta. Il middleware può inserire i dati temporanei che elabora nel Depot per l'utilizzo da parte dei programmi successivi.

Quando un server riceve una richiesta dal browser client, crea un'istanza di Depot. Questa istanza viene distrutta dopo che tutti i middleware e Handler hanno completato l'elaborazione della richiesta.

Ad esempio, possiamo impostare current_user in un middleware di login e poi leggere le informazioni dell'utente corrente nei middleware o Handler successivi.

Comprensione Rapida

Depot viene utilizzato per memorizzare e condividere dati durante l'elaborazione delle richieste. Implementa un contenitore di dati type-safe che supporta due principali pattern di utilizzo:

  1. Memorizzazione Chiave-Valore: Accedi ai valori associati a chiavi stringa tramite i metodi insert/get.
  2. Iniezione di Tipo: Memorizza e recupera valori basati sul tipo tramite i metodi inject/obtain.

Come mostrato negli esempi, Depot è particolarmente utile per passare dati tra middleware e handler. Il middleware può impostare valori in Depot (come informazioni utente, stato di autenticazione), e gli handler successivi possono recuperare questi valori senza calcoli o query ridondanti. Il design di Depot garantisce la coerenza e l'accessibilità dei dati durante l'intera catena di elaborazione delle richieste, rendendolo uno strumento fondamentale per costruire applicazioni web complesse.

main.rs
Cargo.toml
use salvo::prelude::*;

#[handler]
async fn set_user(depot: &mut Depot) {
    depot.insert("user", "client");
}
#[handler]
async fn hello(depot: &mut Depot) -> String {
    format!(
        "Hello {}",
        depot.get::<&str>("user").copied().unwrap_or_default()
    )
}

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

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

    let acceptor = TcpListener::new("0.0.0.0:8698").bind().await;
    Server::new(acceptor).serve(router).await;
}

Impostazione e Recupero Dati tramite insert e get

Come mostrato sopra, puoi inserire chiave e valore in Depot utilizzando insert. Per valori di questo tipo, puoi recuperarli direttamente utilizzando get.

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

Se la chiave non esiste, o se la chiave esiste ma il tipo non corrisponde, restituisce None.

Impostazione e Recupero Dati tramite inject e obtain

A volte, ci sono scenari in cui esiste un'istanza unica per un tipo senza bisogno di relazionarsi a una specifica chiave. Puoi usare inject per inserire dati e poi usare obtain per recuperarli. Questi metodi non richiedono di fornire una chiave.

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

Panoramica dei Metodi della Struttura Depot

CategoriaMetodoDescrizione
Creazione/Capacitànew()Crea un Depot vuoto
with_capacity(capacità)Crea un Depot con la capacità specificata
capacity()Ottiene la capacità
inner()Ottiene un riferimento all'HashMap interno
Iniezione/Recupero di Tipoinject<V>(valore)Inietta un valore per tipo
obtain<T>()Recupera un riferimento al valore iniettato
obtain_mut<T>()Recupera un riferimento mutabile al valore iniettato
contains<T>()Verifica se è contenuto un tipo specifico
scrape<T>()Rimuove e restituisce il valore iniettato
Operazioni Chiave-Valoreinsert(chiave, valore)Inserisce una coppia chiave-valore
get<V>(chiave)Recupera un riferimento al valore associato alla chiave
get_mut<V>(chiave)Recupera un riferimento mutabile al valore associato alla chiave
contains_key(chiave)Verifica se è contenuta una chiave specifica
remove<V>(chiave)Rimuove la chiave e restituisce il valore
delete(chiave)Elimina la coppia chiave-valore