兼容 Tower 中间件
Salvo 通过 tower-compat
功能提供对 tower 生态的兼容性支持. 具体 API 请查看文档.
Tower 核心概念
Tower 是一个服务抽象库,主要基于两个核心 trait:
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;
}
Service
负责处理请求并返回响应,类似于 Salvo 的处理器。
Layer trait
pub trait Layer<S> {
type Service;
fn layer(&self, inner: S) -> Self::Service;
}
Layer
用于包装服务并添加额外功能,类似于 Salvo 的中间件。
Salvo 兼容性支持
Salvo 提供两个关键 trait 实现 Tower 生态系统的兼容:
- TowerLayerCompat:将 Tower 的
Layer
转换为 Salvo 的 Handler
,使其可以作为 Hoop(中间件)使用
- TowerServiceCompat:将 Tower 的
Service
转换为 Salvo 的 Handler
使用示例:
// 使用 Tower 的 RateLimitLayer 并通过 compat() 方法转换为 Salvo 兼容格式
let limit = RateLimitLayer::new(5, Duration::from_secs(30)).compat();
let router = Router::new().hoop(limit).get(hello);
示例代码
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;
}