Compatibilité des Middlewares Tower

Salvo fournit une prise en charge de compatibilité pour l'écosystème Tower via la fonctionnalité tower-compat. Pour les API spécifiques, veuillez consulter la documentation.

Concepts Fondamentaux de Tower

Tower est une bibliothèque d'abstraction de services basée principalement sur deux traits fondamentaux :

Trait Service

pub trait Service<Request> {
    type Response;
    type Error;
    type Future: Future<Output = Result<Self::Response, Self::Error>>;

    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>;
    fn call(&mut self, req: Request) -> Self::Future;
}

Le trait Service est responsable du traitement des requêtes et du renvoi des réponses, similaire aux gestionnaires de Salvo.

Trait Layer

pub trait Layer<S> {
    type Service;
    fn layer(&self, inner: S) -> Self::Service;
}

Le trait Layer est utilisé pour encapsuler des services et ajouter des fonctionnalités supplémentaires, similaire aux middlewares de Salvo.

Prise en Charge de la Compatibilité par Salvo

Salvo fournit deux traits clés pour assurer la compatibilité avec l'écosystème Tower :

  • TowerLayerCompat : Convertit le Layer de Tower en Handler de Salvo, permettant son utilisation en tant que Hoop (middleware).
  • TowerServiceCompat : Convertit le Service de Tower en Handler de Salvo.

Exemple d'utilisation :

// Utilisez RateLimitLayer de Tower et convertissez-le en un format compatible Salvo via la méthode compat()
let limit = RateLimitLayer::new(5, Duration::from_secs(30)).compat();
let router = Router::new().hoop(limit).get(hello);

Exemple de Code

main.rs
Cargo.toml
use salvo::prelude::*;
use tokio::time::Duration;
use tower::limit::RateLimitLayer;

#[handler]
async fn hello() -> &'static str {
    "Hello World"
}

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

    let limit = RateLimitLayer::new(5, Duration::from_secs(30)).compat();
    let acceptor = TcpListener::new("0.0.0.0:8698").bind().await;
    let router = Router::new().hoop(limit).get(hello);
    Server::new(acceptor).serve(router).await;
}