Tower Middleware Compatibility
Salvo provides compatibility support for the Tower ecosystem through the tower-compat
feature. For detailed APIs, please refer to the documentation.
Core Concepts of Tower
Tower is a service abstraction library primarily built around two core traits:
Service Trait
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;
}
The Service
trait handles requests and returns responses, similar to Salvo's handler.
Layer Trait
pub trait Layer<S> {
type Service;
fn layer(&self, inner: S) -> Self::Service;
}
The Layer
trait wraps services to add additional functionality, analogous to Salvo's middleware.
Salvo Compatibility Support
Salvo offers two key traits to enable compatibility with the Tower ecosystem:
- TowerLayerCompat: Converts Tower's
Layer
into Salvo's Handler
, allowing it to be used as a Hoop (middleware).
- TowerServiceCompat: Converts Tower's
Service
into Salvo's Handler
.
Usage Example:
// Apply Tower's RateLimitLayer and convert it to a Salvo-compatible format using compat()
let limit = RateLimitLayer::new(5, Duration::from_secs(30)).compat();
let router = Router::new().hoop(limit).get(hello);
Example Code
with-tower/src/main.rs
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:5800").bind().await;
let router = Router::new().hoop(limit).get(hello);
Server::new(acceptor).serve(router).await;
}