相容 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);

範例程式碼

main.rs
Cargo.toml
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;
}