Convert Figma logo to code with AI

tower-rs logotower

async fn(Request) -> Result<Response, Error>

3,448
272
3,448
76

Top Related Projects

18,202

Ergonomic and modular web framework built with Tokio, Tower, and Hyper

14,343

An HTTP library for Rust

21,219

Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust.

9,488

A super-easy, composable, web server framework for warp speeds.

24,163

A web framework for Rust.

Quick Overview

Tower is a library of modular and reusable components for building robust networking clients and servers in Rust. It provides a powerful middleware system that allows developers to compose various service components, making it easier to build complex, scalable, and maintainable network applications.

Pros

  • Highly modular and composable architecture
  • Extensive middleware ecosystem for common tasks like rate limiting, tracing, and load balancing
  • Excellent integration with other Rust ecosystem projects like Tokio and Hyper
  • Strong focus on performance and low overhead

Cons

  • Steeper learning curve compared to simpler networking libraries
  • Documentation can be sparse or outdated for some components
  • Some advanced features may require a deep understanding of Rust's async ecosystem

Code Examples

  1. Creating a basic service:
use tower::{Service, ServiceBuilder, ServiceExt};
use std::convert::Infallible;

async fn handle(req: String) -> Result<String, Infallible> {
    Ok(format!("Received: {}", req))
}

let service = ServiceBuilder::new()
    .service_fn(handle);
  1. Adding middleware to a service:
use tower::{Service, ServiceBuilder, ServiceExt};
use tower_http::trace::TraceLayer;

let service = ServiceBuilder::new()
    .layer(TraceLayer::new_for_http())
    .service_fn(handle);
  1. Using a load balancer:
use tower::ServiceBuilder;
use tower::load::Load;
use tower::discover::ServiceList;

let services = vec![
    ServiceA::new().map_err(BoxError::from),
    ServiceB::new().map_err(BoxError::from),
];

let balancer = ServiceBuilder::new()
    .layer(Load::new())
    .service(ServiceList::new(services));

Getting Started

To use Tower in your Rust project, add the following to your Cargo.toml:

[dependencies]
tower = "0.4"

Then, in your Rust code:

use tower::{Service, ServiceBuilder, ServiceExt};

async fn my_service(req: Request) -> Result<Response, Error> {
    // Your service logic here
}

let service = ServiceBuilder::new()
    .service_fn(my_service);

// Use the service
let response = service.ready().await?.call(request).await?;

This sets up a basic Tower service. You can then add middleware layers and compose services as needed for your application.

Competitor Comparisons

18,202

Ergonomic and modular web framework built with Tokio, Tower, and Hyper

Pros of Axum

  • Higher-level abstractions for building web applications
  • Built-in routing system with type-safe path extraction
  • Seamless integration with Tokio ecosystem

Cons of Axum

  • Less flexibility for custom middleware implementations
  • Steeper learning curve for developers new to Rust web frameworks

Code Comparison

Axum example:

async fn handler(Path(id): Path<u32>) -> impl IntoResponse {
    format!("User ID: {}", id)
}

let app = Router::new().route("/users/:id", get(handler));

Tower example:

let service = ServiceBuilder::new()
    .layer(TimeoutLayer::new(Duration::from_secs(30)))
    .service(MyService::new());

Key Differences

  • Axum focuses on web application development, while Tower provides a more general-purpose middleware framework
  • Axum offers a more opinionated structure, whereas Tower allows for greater customization
  • Axum leverages Tower's middleware system internally, building upon its foundation

Use Cases

  • Axum: Web APIs, REST services, and full-stack web applications
  • Tower: Generic service composition, middleware creation, and low-level network programming

Community and Ecosystem

  • Both projects are part of the Tokio ecosystem and maintain active communities
  • Axum has gained popularity for web development, while Tower remains a foundational library for service abstraction
14,343

An HTTP library for Rust

Pros of Hyper

  • More mature and widely adopted HTTP library in the Rust ecosystem
  • Provides both client and server implementations for HTTP/1 and HTTP/2
  • Extensive documentation and examples available

Cons of Hyper

  • Focused specifically on HTTP, less flexible for other protocols
  • Steeper learning curve for beginners due to its comprehensive feature set
  • Larger dependency footprint compared to Tower

Code Comparison

Hyper example:

let client = Client::new();
let res = client.get("http://example.com").await?;
println!("Response: {}", res.status());

Tower example:

let service = ServiceBuilder::new()
    .timeout(Duration::from_secs(5))
    .service(MyService);
let response = service.call(Request::new()).await?;

Summary

Hyper is a robust HTTP library offering comprehensive HTTP functionality, while Tower provides a more general-purpose middleware and service abstraction layer. Hyper excels in HTTP-specific scenarios, whereas Tower offers greater flexibility for building various types of services and middleware stacks. The choice between the two depends on the specific requirements of your project and whether you need a dedicated HTTP solution or a more versatile service framework.

21,219

Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust.

Pros of actix-web

  • Full-featured web framework with built-in routing, middleware, and HTTP server
  • High performance and low latency, consistently ranking among the fastest web frameworks
  • Extensive documentation and large community support

Cons of actix-web

  • Steeper learning curve due to its comprehensive feature set
  • More opinionated architecture, which may limit flexibility in some cases
  • Larger codebase and potential overhead for simpler applications

Code Comparison

actix-web:

use actix_web::{web, App, HttpServer, Responder};

async fn hello() -> impl Responder {
    "Hello, World!"
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new().route("/", web::get().to(hello))
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}

Tower:

use tower::{Service, ServiceBuilder, ServiceExt};
use hyper::{Body, Request, Response, Server};

async fn hello(_: Request<Body>) -> Result<Response<Body>, hyper::Error> {
    Ok(Response::new(Body::from("Hello, World!")))
}

#[tokio::main]
async fn main() {
    let service = ServiceBuilder::new().service_fn(hello);
    let addr = ([127, 0, 0, 1], 8080).into();
    Server::bind(&addr).serve(service).await.unwrap();
}
9,488

A super-easy, composable, web server framework for warp speeds.

Pros of Warp

  • Simpler API with a more intuitive routing system
  • Built-in support for WebSockets and Server-Sent Events
  • Faster development time for basic web applications

Cons of Warp

  • Less flexibility for complex middleware configurations
  • Limited to HTTP/HTTPS services, unlike Tower's broader service abstraction
  • Steeper learning curve for advanced customizations

Code Comparison

Warp example:

let hello = warp::path!("hello" / String)
    .map(|name| format!("Hello, {}!", name));

warp::serve(hello).run(([127, 0, 0, 1], 3030)).await;

Tower example:

let svc = ServiceBuilder::new()
    .layer(TimeoutLayer::new(Duration::from_secs(30)))
    .service(HelloWorld);

Server::bind(&"127.0.0.1:3030".parse().unwrap())
    .serve(svc.into_make_service())
    .await?;

Summary

Warp is a high-level web framework built on top of hyper, offering a more opinionated and user-friendly approach to building web services. It excels in rapid development of HTTP-based applications with built-in features like WebSocket support.

Tower, on the other hand, is a lower-level library providing a generic, composable abstraction for asynchronous services. It offers greater flexibility and can be used beyond just HTTP services, making it suitable for a wider range of applications, including gRPC and custom protocols.

Choose Warp for quick web application development, and Tower for more complex, customizable service architectures or non-HTTP applications.

24,163

A web framework for Rust.

Pros of Rocket

  • Simpler and more intuitive API for building web applications
  • Built-in support for templating, form parsing, and JSON serialization
  • Strong focus on compile-time checking and type safety

Cons of Rocket

  • Less flexible middleware system compared to Tower
  • Limited to synchronous request handling
  • Smaller ecosystem and fewer third-party integrations

Code Comparison

Rocket example:

#[get("/<name>/<age>")]
fn hello(name: String, age: u8) -> String {
    format!("Hello, {} year old named {}!", age, name)
}

Tower example:

async fn hello(req: Request<Body>) -> Result<Response<Body>, Infallible> {
    let name = req.uri().path().split('/').nth(1).unwrap_or("World");
    let response = format!("Hello, {}!", name);
    Ok(Response::new(Body::from(response)))
}

Rocket provides a more declarative approach with route annotations and automatic parameter extraction, while Tower offers more flexibility but requires manual request parsing and response construction.

Both frameworks have their strengths, with Rocket excelling in rapid development of straightforward web applications, and Tower providing a more composable foundation for complex service architectures.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Tower

Tower is a library of modular and reusable components for building robust networking clients and servers.

Crates.io Documentation Documentation (master) MIT licensed Build Status Discord chat

Overview

Tower aims to make it as easy as possible to build robust networking clients and servers. It is protocol agnostic, but is designed around a request / response pattern. If your protocol is entirely stream based, Tower may not be a good fit.

Supported Rust Versions

Tower will keep a rolling MSRV (minimum supported Rust version) policy of at least 6 months. When increasing the MSRV, the new Rust version must have been released at least six months ago. The current MSRV is 1.64.0.

Getting Started

If you're brand new to Tower and want to start with the basics we recommend you check out some of our guides.

License

This project is licensed under the MIT license.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Tower by you, shall be licensed as MIT, without any additional terms or conditions.