Depot

Depot se utiliza para almacenar datos temporales involucrados en una única solicitud. El middleware puede colocar los datos temporales que procesa en el Depot para que los utilicen programas posteriores.

Cuando un servidor recibe una solicitud desde el navegador de un cliente, crea una instancia de Depot. Esta instancia se destruye después de que todo el middleware y el Handler hayan terminado de procesar la solicitud.

Por ejemplo, podemos establecer current_user en un middleware de inicio de sesión y luego leer la información del usuario actual en middleware o Handler posteriores.

Comprensión rápida

Depot se utiliza para almacenar y compartir datos durante el procesamiento de solicitudes. Implementa un contenedor de datos seguro en cuanto a tipos que admite dos patrones principales de uso:

  1. Almacenamiento clave-valor: Accede a valores asociados con claves de cadena mediante los métodos insert/get.
  2. Inyección de tipos: Almacena y recupera valores basados en el tipo mediante los métodos inject/obtain.

Como se muestra en los ejemplos, Depot es particularmente útil para pasar datos entre middleware y manejadores. El middleware puede establecer valores en Depot (como información del usuario, estado de autenticación), y los manejadores posteriores pueden recuperar estos valores sin cálculos o consultas redundantes. El diseño de Depot garantiza la consistencia y accesibilidad de los datos a lo largo de toda la cadena de procesamiento de solicitudes, convirtiéndolo en una herramienta central para construir aplicaciones web complejas.

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;
}

Establecer y recuperar datos mediante insert y get

Como se muestra arriba, puedes insertar clave y valor en Depot usando insert. Para valores de este tipo, puedes recuperarlos directamente usando get.

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

Si la clave no existe, o si la clave existe pero el tipo no coincide, devuelve None.

Establecer y recuperar datos mediante inject y obtain

A veces, existen escenarios donde hay una instancia única para un tipo sin necesidad de relacionarla con una clave específica. Puedes usar inject para insertar datos y luego usar obtain para recuperarlos. Estos métodos no requieren que proporciones una clave.

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

Resumen de métodos de la estructura Depot

CategoríaMétodoDescripción
Creación/Capacidadnew()Crea un Depot vacío
with_capacity(capacidad)Crea un Depot con la capacidad especificada
capacity()Obtiene la capacidad
inner()Obtiene una referencia al HashMap interno
Inyección/Recuperación de tiposinject<V>(valor)Inyecta un valor por tipo
obtain<T>()Recupera una referencia al valor inyectado
obtain_mut<T>()Recupera una referencia mutable al valor inyectado
contains<T>()Verifica si contiene un tipo específico
scrape<T>()Elimina y devuelve el valor inyectado
Operaciones clave-valorinsert(clave, valor)Inserta un par clave-valor
get<V>(clave)Recupera una referencia al valor asociado con la clave
get_mut<V>(clave)Recupera una referencia mutable al valor asociado con la clave
contains_key(clave)Verifica si contiene una clave específica
remove<V>(clave)Elimina la clave y devuelve el valor
delete(clave)Elimina el par clave-valor