---
title: "Tower Rust: Middleware, Resiliência e Axum em Produção"
url: "https://rustlang.com.br/ecossistema/tower/"
markdown_url: "https://rustlang.com.br/ecossistema/tower.MD"
description: "Guia completo de Tower em Rust: Service, Layer, tower-http, Axum, Tonic, timeouts, retries, rate limit, observabilidade e serviços resilientes em produção."
date: ""
author: ""
---

# Tower Rust: Middleware, Resiliência e Axum em Produção

Guia completo de Tower em Rust: Service, Layer, tower-http, Axum, Tonic, timeouts, retries, rate limit, observabilidade e serviços resilientes em produção.


## Introdução

O **Tower** é uma biblioteca de abstrações de serviço para Rust que define como componentes de rede se comunicam de forma composável e modular. Ele fornece o trait `Service` -- uma interface comum para funções assíncronas que recebem uma requisição e retornam uma resposta -- e um sistema de `Layer` para empilhar middleware de forma elegante.

Se você já usou Axum, Hyper, Tonic ou Reqwest, você já usou Tower indiretamente. Esses frameworks utilizam o trait `Service` do Tower como base da sua arquitetura, permitindo que middleware escritos para um framework funcionem em qualquer outro que siga o mesmo padrão.

## Tower Rust em 2026: onde ele encaixa

Quem pesquisa **Tower Rust** normalmente está tentando sair do tutorial de rota HTTP e chegar em um serviço operável: como colocar timeout sem copiar código em todo handler, limitar concorrência antes do banco cair, registrar latência com `TraceLayer`, aplicar CORS, compactar resposta, propagar request ID ou reutilizar a mesma política em [Axum](/ecossistema/axum/) e [Tonic](/ecossistema/tonic/). Tower é a camada que transforma essas decisões em composição, não em cola espalhada.

Na prática, Tower fica entre o runtime e os frameworks. [Tokio](/ecossistema/tokio/) executa as tarefas assíncronas, Hyper fala HTTP, Axum organiza rotas, Tonic fala gRPC, e Tower oferece o modelo de `Service` e `Layer` para envolver tudo com comportamento operacional. O pacote `tower-http` traz as peças mais usadas em APIs: `TraceLayer`, `TimeoutLayer`, CORS, compressão, request ID, arquivos estáticos e autenticação básica. Quando a aplicação cresce, esse vocabulário evita que cada equipe invente um middleware incompatível.

Para SEO e carreira, Tower conecta vários clusters importantes do site: [serviços resilientes com Tower, Axum e Tokio](/blog/rust-servicos-resilientes-tower-axum-2026/), [OpenTelemetry em Rust](/blog/rust-opentelemetry-producao-2026/), [gRPC com Tonic](/blog/rust-grpc-tonic-microservicos-2026/), [deploy Axum com Docker Compose e PostgreSQL](/blog/deploy-axum-docker-compose-postgresql-2026/) e [backend Rust](/carreira/nicho-web-backend/). Muitas [vagas Rust](/vagas/) não citam Tower no título, mas pedem exatamente seus conceitos: middleware, observabilidade, rate limit, resiliência, APIs internas, plataforma e sistemas distribuídos.

Use esta página como referência de base. Se o objetivo é construir portfólio, crie uma API Axum pequena com `TraceLayer`, timeout, limite de concorrência e testes de middleware. Se o objetivo é entrevista, saiba explicar a diferença entre handler, `Service`, `Layer`, `ServiceBuilder` e `tower-http`. Para [empresas que usam Rust](/empresas/), essa maturidade vale mais do que apenas saber declarar uma rota.

### Por que o Tower é importante?

- **Composabilidade**: empilhe middleware como blocos de construção
- **Reutilização**: o mesmo middleware funciona com Axum, Hyper, Tonic, etc.
- **Middleware pronto**: timeout, rate limiting, retry, load balancing, circuit breaker
- **Testabilidade**: cada camada pode ser testada isoladamente
- **Performance**: abstrações de custo zero com trait objects opcionais
- **Ecossistema**: é a cola que conecta todo o stack de rede do Rust

## Instalação

Adicione o Tower ao seu `Cargo.toml`:

```toml
[dependencies]
tower = { version = "0.5", features = ["full"] }
tokio = { version = "1", features = ["full"] }
```

Features disponíveis:

```toml
[dependencies]
tower = { version = "0.5", features = [
    "timeout",     # Middleware de timeout
    "retry",       # Middleware de retry
    "limit",       # Rate limiting e concurrency limiting
    "buffer",      # Buffer de requisições
    "load-shed",   # Descarte de carga
    "balance",     # Load balancing
    "discover",    # Service discovery
    "filter",      # Filtragem de requisições
    "hedge",       # Hedged requests
    "util",        # Utilitários gerais
] }
```

Para usar com Axum, você também vai precisar do `tower-http`:

```toml
[dependencies]
tower = "0.5"
tower-http = { version = "0.6", features = [
    "cors",        # CORS
    "trace",       # Tracing/logging
    "compression-gzip",  # Compressão
    "timeout",     # Timeout de resposta
    "auth",        # Autenticação
    "request-id",  # ID de requisição
] }
```

## Uso Básico

### O trait Service

O coração do Tower é o trait `Service`:

```rust
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
use tower::Service;

// O trait Service simplificado:
// 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;
// }

// Implementando um Service manualmente
#[derive(Clone)]
struct MeuServico;

impl Service<String> for MeuServico {
    type Response = String;
    type Error = std::convert::Infallible;
    type Future = Pin<Box<dyn Future<Output = Result<String, Self::Error>> + Send>>;

    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
        Poll::Ready(Ok(())) // Sempre pronto
    }

    fn call(&mut self, req: String) -> Self::Future {
        Box::pin(async move {
            Ok(format!("Olá, {}!", req))
        })
    }
}

#[tokio::main]
async fn main() {
    let mut servico = MeuServico;

    // Verificar se o serviço está pronto
    use tower::ServiceExt; // Importa métodos utilitários
    let resposta = servico.ready().await.unwrap().call("Rust".to_string()).await.unwrap();
    println!("{}", resposta); // "Olá, Rust!"
}
```

### ServiceBuilder e Layers

O `ServiceBuilder` permite empilhar middleware de forma declarativa:

```rust
use std::time::Duration;
use tower::ServiceBuilder;
use tower::timeout::TimeoutLayer;
use tower::limit::RateLimitLayer;
use tower::limit::ConcurrencyLimitLayer;

// Empilhar middleware com ServiceBuilder
fn criar_service_com_middleware() {
    let _service = ServiceBuilder::new()
        // Timeout de 30 segundos
        .layer(TimeoutLayer::new(Duration::from_secs(30)))
        // Limite de 100 requisições por segundo
        .layer(RateLimitLayer::new(100, Duration::from_secs(1)))
        // Máximo de 50 requisições simultâneas
        .layer(ConcurrencyLimitLayer::new(50))
        // Serviço base (o handler real)
        .service_fn(|req: String| async move {
            Ok::<_, std::convert::Infallible>(format!("Processado: {}", req))
        });
}
```

### Usando com Axum

O caso de uso mais comum do Tower é adicionar middleware a aplicações Axum:

```rust
use axum::{routing::get, Router};
use std::time::Duration;
use tower::ServiceBuilder;
use tower_http::cors::CorsLayer;
use tower_http::timeout::TimeoutLayer;
use tower_http::trace::TraceLayer;

async fn handler() -> &'static str {
    "Olá, mundo!"
}

#[tokio::main]
async fn main() {
    let app = Router::new()
        .route("/", get(handler))
        .layer(
            ServiceBuilder::new()
                // Tracing/logging de requisições
                .layer(TraceLayer::new_for_http())
                // Timeout de resposta
                .layer(TimeoutLayer::new(Duration::from_secs(30)))
                // CORS
                .layer(CorsLayer::permissive())
        );

    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
    axum::serve(listener, app).await.unwrap();
}
```

## Recursos Avançados

### Middleware de Timeout

```rust
use std::time::Duration;
use tower::timeout::Timeout;
use tower::ServiceExt;

async fn exemplo_timeout() {
    // Serviço que demora muito
    let servico_lento = tower::service_fn(|_req: ()| async {
        tokio::time::sleep(Duration::from_secs(10)).await;
        Ok::<_, std::convert::Infallible>("Concluído")
    });

    // Adicionar timeout de 2 segundos
    let mut servico_com_timeout = Timeout::new(servico_lento, Duration::from_secs(2));

    match servico_com_timeout.ready().await.unwrap().call(()).await {
        Ok(resp) => println!("Resposta: {}", resp),
        Err(e) => println!("Timeout! Erro: {}", e), // Vai cair aqui
    }
}
```

### Middleware de Rate Limiting

```rust
use std::time::Duration;
use tower::limit::RateLimit;
use tower::ServiceExt;

async fn exemplo_rate_limit() {
    let servico = tower::service_fn(|req: u32| async move {
        Ok::<_, std::convert::Infallible>(format!("Processado: {}", req))
    });

    // Máximo 5 requisições por segundo
    let mut servico_limitado = RateLimit::new(servico, 5, Duration::from_secs(1));

    for i in 0..10 {
        match servico_limitado.ready().await {
            Ok(svc) => {
                let resp = svc.call(i).await.unwrap();
                println!("{}", resp);
            }
            Err(e) => println!("Rate limited: {}", e),
        }
    }
}
```

### Middleware de Retry

```rust
use std::time::Duration;
use tower::retry::{Policy, Retry};
use tower::ServiceExt;

// Política de retry customizada
#[derive(Clone)]
struct MinhaRetryPolicy {
    tentativas_restantes: u32,
}

impl Policy<String, String, String> for MinhaRetryPolicy {
    type Future = std::future::Ready<()>;

    fn retry(
        &mut self,
        _req: &mut String,
        resultado: &mut Result<String, String>,
    ) -> Option<Self::Future> {
        match resultado {
            Ok(_) => None, // Sucesso, não tentar novamente
            Err(_) if self.tentativas_restantes > 0 => {
                self.tentativas_restantes -= 1;
                println!(
                    "Retry! Tentativas restantes: {}",
                    self.tentativas_restantes
                );
                Some(std::future::ready(()))
            }
            Err(_) => None, // Sem tentativas restantes
        }
    }

    fn clone_request(&mut self, req: &String) -> Option<String> {
        Some(req.clone())
    }
}

async fn exemplo_retry() {
    let mut contador = 0u32;

    let servico = tower::service_fn(move |_req: String| {
        contador += 1;
        async move {
            if contador < 3 {
                Err::<String, String>("Falha temporária".to_string())
            } else {
                Ok("Sucesso após retries!".to_string())
            }
        }
    });

    let policy = MinhaRetryPolicy {
        tentativas_restantes: 3,
    };

    let mut servico_com_retry = Retry::new(policy, servico);

    let resultado = servico_com_retry
        .ready()
        .await
        .unwrap()
        .call("teste".to_string())
        .await;

    println!("Resultado: {:?}", resultado);
}
```

### Middleware de Concurrency Limit

```rust
use tower::limit::ConcurrencyLimit;
use tower::ServiceExt;

async fn exemplo_concurrency_limit() {
    let servico = tower::service_fn(|req: u32| async move {
        // Simular processamento demorado
        tokio::time::sleep(std::time::Duration::from_millis(100)).await;
        Ok::<_, std::convert::Infallible>(format!("Processado: {}", req))
    });

    // Máximo 3 requisições simultâneas
    let servico_limitado = ConcurrencyLimit::new(servico, 3);

    // As requisições além do limite vão esperar
    let mut handles = vec![];
    for i in 0..10 {
        let mut svc = servico_limitado.clone();
        handles.push(tokio::spawn(async move {
            let resp = svc.ready().await.unwrap().call(i).await.unwrap();
            println!("{}", resp);
        }));
    }

    for h in handles {
        let _ = h.await;
    }
}
```

### Criando middleware customizado

```rust
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
use std::time::Instant;
use tower::{Layer, Service};

// === Layer: fábrica de middleware ===

#[derive(Clone)]
struct LoggingLayer;

impl<S> Layer<S> for LoggingLayer {
    type Service = LoggingMiddleware<S>;

    fn layer(&self, inner: S) -> Self::Service {
        LoggingMiddleware { inner }
    }
}

// === Middleware: o wrapper do serviço ===

#[derive(Clone)]
struct LoggingMiddleware<S> {
    inner: S,
}

impl<S, Req> Service<Req> for LoggingMiddleware<S>
where
    S: Service<Req>,
    S::Future: Send + 'static,
    S::Response: std::fmt::Debug + Send + 'static,
    S::Error: std::fmt::Debug + Send + 'static,
    Req: std::fmt::Debug + Send + 'static,
{
    type Response = S::Response;
    type Error = S::Error;
    type Future = Pin<Box<dyn Future<Output = Result<S::Response, S::Error>> + Send>>;

    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
        self.inner.poll_ready(cx)
    }

    fn call(&mut self, req: Req) -> Self::Future {
        let inicio = Instant::now();
        println!("[LOG] Requisição recebida: {:?}", req);

        let future = self.inner.call(req);

        Box::pin(async move {
            let resultado = future.await;
            let duracao = inicio.elapsed();

            match &resultado {
                Ok(resp) => println!("[LOG] Resposta OK em {:?}: {:?}", duracao, resp),
                Err(err) => println!("[LOG] Erro em {:?}: {:?}", duracao, err),
            }

            resultado
        })
    }
}
```

### Middleware com estado compartilhado

```rust
use std::sync::Arc;
use std::sync::atomic::{AtomicU64, Ordering};
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
use tower::{Layer, Service};

// Métricas compartilhadas
#[derive(Default)]
struct Metricas {
    total_requisicoes: AtomicU64,
    total_erros: AtomicU64,
    total_sucesso: AtomicU64,
}

// Layer com estado compartilhado
#[derive(Clone)]
struct MetricasLayer {
    metricas: Arc<Metricas>,
}

impl MetricasLayer {
    fn new() -> (Self, Arc<Metricas>) {
        let metricas = Arc::new(Metricas::default());
        (
            Self {
                metricas: metricas.clone(),
            },
            metricas,
        )
    }
}

impl<S> Layer<S> for MetricasLayer {
    type Service = MetricasMiddleware<S>;

    fn layer(&self, inner: S) -> Self::Service {
        MetricasMiddleware {
            inner,
            metricas: self.metricas.clone(),
        }
    }
}

#[derive(Clone)]
struct MetricasMiddleware<S> {
    inner: S,
    metricas: Arc<Metricas>,
}

impl<S, Req> Service<Req> for MetricasMiddleware<S>
where
    S: Service<Req>,
    S::Future: Send + 'static,
    S::Response: Send + 'static,
    S::Error: Send + 'static,
    Req: Send + 'static,
{
    type Response = S::Response;
    type Error = S::Error;
    type Future = Pin<Box<dyn Future<Output = Result<S::Response, S::Error>> + Send>>;

    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
        self.inner.poll_ready(cx)
    }

    fn call(&mut self, req: Req) -> Self::Future {
        self.metricas.total_requisicoes.fetch_add(1, Ordering::Relaxed);
        let metricas = self.metricas.clone();
        let future = self.inner.call(req);

        Box::pin(async move {
            let resultado = future.await;
            match &resultado {
                Ok(_) => metricas.total_sucesso.fetch_add(1, Ordering::Relaxed),
                Err(_) => metricas.total_erros.fetch_add(1, Ordering::Relaxed),
            };
            resultado
        })
    }
}

// Uso
async fn exemplo_metricas() {
    let (layer, metricas) = MetricasLayer::new();

    let _service = tower::ServiceBuilder::new()
        .layer(layer)
        .service_fn(|req: String| async move {
            Ok::<_, String>(format!("OK: {}", req))
        });

    // Em outro lugar, ler as métricas
    println!("Total: {}", metricas.total_requisicoes.load(Ordering::Relaxed));
    println!("Sucesso: {}", metricas.total_sucesso.load(Ordering::Relaxed));
    println!("Erros: {}", metricas.total_erros.load(Ordering::Relaxed));
}
```

### Integração com tower-http para aplicações web

```rust
use axum::{
    extract::Request,
    http::StatusCode,
    middleware::{self, Next},
    response::Response,
    routing::get,
    Router,
};
use std::time::Duration;
use tower::ServiceBuilder;
use tower_http::{
    compression::CompressionLayer,
    cors::{Any, CorsLayer},
    request_id::{MakeRequestUuid, PropagateRequestIdLayer, SetRequestIdLayer},
    timeout::TimeoutLayer,
    trace::TraceLayer,
};

async fn handler() -> &'static str {
    "API funcionando!"
}

async fn saude() -> &'static str {
    "OK"
}

fn criar_app() -> Router {
    // CORS configurado
    let cors = CorsLayer::new()
        .allow_origin(Any)
        .allow_methods(Any)
        .allow_headers(Any);

    Router::new()
        .route("/", get(handler))
        .route("/saude", get(saude))
        .layer(
            ServiceBuilder::new()
                // ID único para cada requisição
                .layer(SetRequestIdLayer::x_request_id(MakeRequestUuid))
                .layer(PropagateRequestIdLayer::x_request_id())
                // Logging/tracing
                .layer(TraceLayer::new_for_http())
                // Timeout
                .layer(TimeoutLayer::new(Duration::from_secs(30)))
                // Compressão
                .layer(CompressionLayer::new())
                // CORS
                .layer(cors)
        )
}
```

## Boas Práticas

### 1. Ordem dos layers importa

Os layers são aplicados de fora para dentro. O primeiro layer no `ServiceBuilder` é o mais externo:

```rust
use tower::ServiceBuilder;
use tower::timeout::TimeoutLayer;
use tower::limit::RateLimitLayer;
use std::time::Duration;

fn exemplo_ordem() {
    let _service = ServiceBuilder::new()
        // 1. Timeout (mais externo) - cancela se tudo demorar mais que 30s
        .layer(TimeoutLayer::new(Duration::from_secs(30)))
        // 2. Rate limit - limita ANTES de processar
        .layer(RateLimitLayer::new(100, Duration::from_secs(1)))
        // 3. Serviço base (mais interno)
        .service_fn(|_req: ()| async { Ok::<_, String>("OK".to_string()) });
}
```

### 2. Use ServiceBuilder para composição legível

```rust
use tower::ServiceBuilder;
use std::time::Duration;

// Bom: ServiceBuilder com layers nomeados
fn criar_service_bom() {
    let _svc = ServiceBuilder::new()
        .layer(tower::timeout::TimeoutLayer::new(Duration::from_secs(30)))
        .layer(tower::limit::ConcurrencyLimitLayer::new(100))
        .service_fn(|_r: ()| async { Ok::<_, String>("OK".to_string()) });
}
```

### 3. Extraia middleware reutilizável em crates separados

```rust
// meu_middleware/src/lib.rs
use tower::Layer;

/// Layer de autenticação reutilizável
#[derive(Clone)]
pub struct AuthLayer {
    secret: String,
}

impl AuthLayer {
    pub fn new(secret: impl Into<String>) -> Self {
        Self {
            secret: secret.into(),
        }
    }
}

impl<S> Layer<S> for AuthLayer {
    type Service = AuthMiddleware<S>;

    fn layer(&self, inner: S) -> Self::Service {
        AuthMiddleware {
            inner,
            secret: self.secret.clone(),
        }
    }
}

#[derive(Clone)]
pub struct AuthMiddleware<S> {
    inner: S,
    secret: String,
}
```

### 4. Teste middleware isoladamente

```rust
#[cfg(test)]
mod tests {
    use super::*;
    use tower::ServiceExt;

    #[tokio::test]
    async fn test_logging_middleware() {
        // Serviço mock
        let servico = tower::service_fn(|_req: String| async {
            Ok::<_, String>("resposta".to_string())
        });

        // Aplicar o middleware
        let mut servico_com_log = LoggingLayer.layer(servico);

        // Testar
        let resultado = servico_com_log
            .ready()
            .await
            .unwrap()
            .call("teste".to_string())
            .await;

        assert_eq!(resultado.unwrap(), "resposta");
    }

    #[tokio::test]
    async fn test_metricas_middleware() {
        let (layer, metricas) = MetricasLayer::new();

        let servico = tower::service_fn(|_req: u32| async {
            Ok::<_, String>("ok".to_string())
        });

        let mut svc = layer.layer(servico);

        // Fazer 3 requisições
        for i in 0..3 {
            svc.ready().await.unwrap().call(i).await.unwrap();
        }

        assert_eq!(metricas.total_requisicoes.load(std::sync::atomic::Ordering::Relaxed), 3);
        assert_eq!(metricas.total_sucesso.load(std::sync::atomic::Ordering::Relaxed), 3);
    }
}
```

## Exemplos Práticos

### Middleware completo de logging de requisições HTTP

```rust
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
use std::time::Instant;
use tower::{Layer, Service};
use hyper::{Request, Response, body::Bytes};
use http_body_util::Full;

#[derive(Clone)]
pub struct RequestLoggerLayer;

impl<S> Layer<S> for RequestLoggerLayer {
    type Service = RequestLogger<S>;

    fn layer(&self, inner: S) -> Self::Service {
        RequestLogger { inner }
    }
}

#[derive(Clone)]
pub struct RequestLogger<S> {
    inner: S,
}

impl<S, B> Service<Request<B>> for RequestLogger<S>
where
    S: Service<Request<B>, Response = Response<Full<Bytes>>> + Clone + Send + 'static,
    S::Future: Send + 'static,
    S::Error: std::fmt::Display + Send + 'static,
    B: Send + 'static,
{
    type Response = Response<Full<Bytes>>;
    type Error = S::Error;
    type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;

    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
        self.inner.poll_ready(cx)
    }

    fn call(&mut self, req: Request<B>) -> Self::Future {
        let metodo = req.method().clone();
        let uri = req.uri().clone();
        let versao = req.version();
        let user_agent = req
            .headers()
            .get("user-agent")
            .and_then(|v| v.to_str().ok())
            .unwrap_or("desconhecido")
            .to_string();

        let inicio = Instant::now();
        let future = self.inner.call(req);

        Box::pin(async move {
            let resultado = future.await;
            let duracao = inicio.elapsed();

            match &resultado {
                Ok(resp) => {
                    let status = resp.status();
                    let nivel = if status.is_success() {
                        "INFO"
                    } else if status.is_client_error() {
                        "WARN"
                    } else {
                        "ERROR"
                    };

                    println!(
                        "[{}] {} {} {:?} -> {} ({:?}) UA: {}",
                        nivel, metodo, uri, versao, status, duracao, user_agent
                    );
                }
                Err(err) => {
                    println!(
                        "[ERROR] {} {} -> Erro: {} ({:?})",
                        metodo, uri, err, duracao
                    );
                }
            }

            resultado
        })
    }
}
```

### Stack completo de middleware para produção com Axum

```rust
use axum::{
    body::Body,
    http::{header, Method, StatusCode},
    response::IntoResponse,
    routing::{get, post},
    Json, Router,
};
use serde_json::json;
use std::time::Duration;
use tower::ServiceBuilder;
use tower_http::{
    compression::CompressionLayer,
    cors::CorsLayer,
    timeout::TimeoutLayer,
    trace::TraceLayer,
};

async fn listar_itens() -> impl IntoResponse {
    Json(json!({
        "itens": [
            {"id": 1, "nome": "Item 1"},
            {"id": 2, "nome": "Item 2"},
        ]
    }))
}

async fn criar_item(Json(body): Json<serde_json::Value>) -> impl IntoResponse {
    (
        StatusCode::CREATED,
        Json(json!({
            "criado": true,
            "dados": body
        })),
    )
}

async fn saude() -> impl IntoResponse {
    Json(json!({"status": "ok", "versao": "1.0.0"}))
}

fn criar_app_producao() -> Router {
    // Configurar CORS para produção
    let cors = CorsLayer::new()
        .allow_origin([
            "https://meusite.com.br".parse().unwrap(),
            "https://admin.meusite.com.br".parse().unwrap(),
        ])
        .allow_methods([Method::GET, Method::POST, Method::PUT, Method::DELETE])
        .allow_headers([header::CONTENT_TYPE, header::AUTHORIZATION])
        .max_age(Duration::from_secs(3600));

    // Stack de middleware
    let middleware_stack = ServiceBuilder::new()
        // Tracing
        .layer(TraceLayer::new_for_http())
        // Timeout global
        .layer(TimeoutLayer::new(Duration::from_secs(30)))
        // Compressão de resposta
        .layer(CompressionLayer::new())
        // CORS
        .layer(cors);

    Router::new()
        .route("/saude", get(saude))
        .route("/itens", get(listar_itens).post(criar_item))
        .layer(middleware_stack)
}

#[tokio::main]
async fn main() {
    // Inicializar tracing
    tracing_subscriber::fmt::init();

    let app = criar_app_producao();

    println!("Servidor de produção em http://0.0.0.0:3000");
    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
    axum::serve(listener, app).await.unwrap();
}
```

## Comparação com Alternativas

| Característica | Tower | actix-web Middleware | Warp Filters |
|---|---|---|---|
| **Abordagem** | Service + Layer | Transform trait | Filter composition |
| **Composabilidade** | Excelente | Boa | Boa |
| **Reutilização** | Cross-framework | Actix-only | Warp-only |
| **Middleware prontos** | tower + tower-http | actix-web embutido | Warp embutido |
| **Tipagem** | Forte | Forte | Forte (tipos complexos) |
| **Curva de aprendizado** | Média-alta | Média | Média-alta |
| **Ecossistema** | Axum, Hyper, Tonic | Actix Web | Warp |

- **Tower** vs **Actix Web Middleware**: Tower é cross-framework, enquanto middleware do Actix só funciona com Actix Web. Se usar Axum/Hyper/Tonic, Tower é a escolha natural.
- **Tower** vs **Warp Filters**: Warp usa composição de filtros que é conceitualmente diferente. Tower é mais flexível e reutilizável entre frameworks.
- **Quando usar Tower diretamente**: quando precisa de middleware que funcione em múltiplos frameworks ou quando está construindo infraestrutura de rede customizada.

## Conclusão

O Tower é a infraestrutura invisível que torna o ecossistema de rede do Rust tão poderoso e composável. Mesmo que você nunca crie um `Layer` customizado, entender como o Tower funciona vai ajudá-lo a usar melhor frameworks como Axum e Tonic, e a aproveitar a rica biblioteca de middleware disponível.

A chave do Tower é a separação clara entre o que um serviço faz (implementação do `Service` trait) e como ele é decorado (composição de `Layer`s). Essa separação permite construir stacks de middleware complexos de forma legível e testável.

Para aplicações modernas, o ganho não é apenas elegância de código. Tower ajuda a transformar requisitos de produção em camadas auditáveis: timeout, limite de concorrência, retry, tracing, CORS, compressão e autenticação ficam próximos da borda do serviço, com testes próprios e comportamento previsível. Isso reduz regressões quando uma API cresce de um CRUD local para um serviço usado por clientes, workers, gateways ou outros microsserviços.

Se você quer usar Tower como diferencial profissional, conecte a prática com páginas complementares: comece por [Axum](/ecossistema/axum/) para APIs HTTP, use [Tracing](/ecossistema/tracing/) para observar spans e eventos, aprofunde [Tonic](/ecossistema/tonic/) quando o problema pedir gRPC e leia [serviços resilientes com Tower, Axum e Tokio](/blog/rust-servicos-resilientes-tower-axum-2026/) para entender timeouts, retries e load shedding em contexto. Depois compare esse conhecimento com [vagas Rust](/vagas/) e com a trilha de [backend Rust](/carreira/nicho-web-backend/) para montar um portfólio mais alinhado ao mercado.

### Próximos passos

- Use **tower-http** para middleware HTTP pronto: CORS, compressão, tracing, timeout e request ID
- Explore [Axum](/ecossistema/axum/) para ver Tower em ação em um framework web completo
- Estude [Tonic](/ecossistema/tonic/) para usar Tower com gRPC e Protocol Buffers
- Aprenda [Tracing](/ecossistema/tracing/) e [OpenTelemetry](/blog/rust-opentelemetry-producao-2026/) para observabilidade dos seus serviços Tower
- Conecte a prática com [vagas Rust](/vagas/), [empresas que usam Rust](/empresas/) e [backend Rust](/carreira/nicho-web-backend/)
