3 stable releases
Uses new Rust 2024
| 1.0.2 | Aug 27, 2025 |
|---|---|
| 1.0.1 | Aug 24, 2025 |
| 1.0.0 | Aug 22, 2025 |
#1102 in Network programming
93 downloads per month
505KB
12K
SLoC
Web Server Abstraction
An ergonomic abstraction layer over popular Rust web frameworks# Use specific framework adapters
[cfg(feature = "axum")]
let server = WebServer::with_axum_adapter();
[cfg(feature = "actix-web")]
let server = WebServer::with_actix_adapter();
[cfg(feature = "warp")]
let server = WebServer::with_warp_adapter();
[cfg(feature = "rocket")]
let server = WebServer::with_rocket_adapter();
[cfg(feature = "salvo")]
let server = WebServer::with_salvo_adapter();
[cfg(feature = "poem")]
let server = WebServer::with_poem_adapter();
// Or use the mock adapter for testing let server = WebServer::with_mock_adapter();ou to write web applications once and run them on any supported framework.
Features
- Framework Agnostic: Write once, run on any supported framework
- Type Safe: Leverages Rust's type system for compile-time guarantees
- Async First: Built for modern async Rust with native async/await support
- Middleware Support: Composable middleware system for cross-cutting concerns
- Tower Integration: Built on the Tower ecosystem for compatibility
- Ergonomic API: Clean, intuitive API that's easy to learn and use
- Advanced Routing: Path parameters (
:id) and wildcards (*file) support - WebSocket Ready: Built-in WebSocket upgrade handling and message types
- HTTP Method Shortcuts: Convenient
.get(),.post(),.put(), etc. methods - Rich Middleware: 9+ built-in middleware types for common web patterns
- Performance Optimized: Comprehensive benchmarking and profiling infrastructure
Supported Frameworks
| Framework | Feature Flag | Status |
|---|---|---|
| Mock (Testing) | Default | ✅ Complete |
| Axum | axum |
✅ Complete |
| Actix-Web | actix-web |
✅ Complete |
| Warp | warp |
✅ Complete |
| Rocket | rocket |
✅ Complete |
| Salvo | salvo |
✅ Complete |
| Poem | poem |
✅ Complete |
Note: All framework adapters are production-ready and fully tested with their latest versions.
Quick Start
Add this to your Cargo.toml:
[dependencies]
web-server-abstraction = "1.0.2" # Includes Axum support by default
# Or explicitly enable specific framework features
web-server-abstraction = { version = "1.0.2", features = ["axum"] }
# Enable multiple frameworks
web-server-abstraction = { version = "1.0.2", features = ["axum", "rocket", "poem"] }
Basic Example
use web_server_abstraction::{
WebServer, HttpMethod, Response, StatusCode,
middleware::{LoggingMiddleware, CorsMiddleware},
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let server = WebServer::new()
// Add middleware
.middleware(LoggingMiddleware::new())
.middleware(CorsMiddleware::new().allow_origin("*"))
// Add routes
.route("/", HttpMethod::GET, |_req| async {
Ok(Response::ok().body("Hello, World!"))
})
.route("/health", HttpMethod::GET, |_req| async {
Ok(Response::ok().body("OK"))
})
.route("/users", HttpMethod::POST, |req| async {
// Parse JSON body
let user: serde_json::Value = req.json().await?;
Ok(Response::new(StatusCode::CREATED)
.header("content-type", "application/json")
.body(serde_json::to_string(&user)?))
});
// Bind and run the server
let bound_server = server.bind("127.0.0.1:3000").await?;
println!("Server running on http://127.0.0.1:3000");
bound_server.run().await?;
Ok(())
}
Framework-Specific Adapters
use web_server_abstraction::WebServer;
// Use specific framework adapters
#[cfg(feature = "axum")]
let server = WebServer::with_axum_adapter();
#[cfg(feature = "actix-web")]
let server = WebServer::with_actix_adapter();
#[cfg(feature = "warp")]
let server = WebServer::with_warp_adapter();
// Or use the mock adapter for testing
let server = WebServer::with_mock_adapter();
Architecture
Core Abstractions
The crate is built around several key abstractions:
- WebServer: The main entry point for building web applications
- Handler: Trait for request handlers that convert requests to responses
- Middleware: Composable middleware for cross-cutting concerns
- Adapter: Framework-specific implementations that bridge to actual web frameworks
Type System
// Core types are standardized across frameworks
pub struct Request { /* ... */ }
pub struct Response { /* ... */ }
pub enum HttpMethod { GET, POST, PUT, DELETE, /* ... */ }
pub struct StatusCode(pub u16);
Middleware System
Built-in middleware includes:
- LoggingMiddleware: Request/response logging with configurable detail levels
- CorsMiddleware: Cross-Origin Resource Sharing with full configuration support
- AuthMiddleware: Authentication checks with bearer token validation
- TimeoutMiddleware: Request timeouts with configurable durations
- RateLimitMiddleware: Rate limiting with sliding window algorithm
- CompressionMiddleware: Response compression (gzip, deflate)
- SecurityHeadersMiddleware: Security headers (HSTS, CSP, X-Frame-Options, etc.)
- MetricsMiddleware: Request metrics collection and monitoring
- CacheMiddleware: Response caching with TTL and invalidation strategies
use web_server_abstraction::middleware::*;
let server = WebServer::new()
.middleware(LoggingMiddleware::new().log_bodies(true))
.middleware(CorsMiddleware::new()
.allow_origin("https://example.com")
.allow_methods(vec!["GET".to_string(), "POST".to_string()])
.allow_credentials(true))
.middleware(AuthMiddleware::new()
.with_bearer_tokens(vec!["secret-token".to_string()]))
.middleware(RateLimitMiddleware::new(100, Duration::from_secs(60)))
.middleware(CompressionMiddleware::new().min_size(1024))
.middleware(SecurityHeadersMiddleware::new())
.middleware(MetricsMiddleware::new())
.middleware(CacheMiddleware::new(Duration::from_secs(300)));
Framework Integration Plan
Current Design Principles
- Common HTTP Abstractions: Use standardized types from the
httpcrate - Tower Compatibility: Leverage the Tower ecosystem where possible
- Zero-Cost Abstractions: Minimal runtime overhead
- Ergonomic APIs: Focus on developer experience
Adapter Implementation Strategy
Each framework adapter follows this pattern:
// 1. Convert our types to framework types
fn convert_request(req: Request) -> FrameworkRequest;
fn convert_response(resp: FrameworkResponse) -> Response;
// 2. Implement the adapter interface
impl FrameworkAdapter {
pub async fn bind(&mut self, addr: &str) -> Result<()>;
pub async fn run(self) -> Result<()>;
pub fn route(&mut self, path: &str, method: HttpMethod, handler: HandlerFn);
pub fn middleware(&mut self, middleware: Box<dyn Middleware>);
}
Integration Status
Axum ✅ COMPLETE
- ✅ Basic route registration
- ✅ Request/response type conversion
- ✅ Middleware integration with Tower ServiceBuilder
- ✅ Full HTTP method support
- ✅ Async handler support
Actix-Web ✅ COMPLETE
- ✅ Route registration and handlers
- ✅ Request/response conversion
- ✅ HTTP server binding and running
- ✅ Built-in logging middleware
- ✅ Full HTTP method support
Warp ✅ COMPLETE
- ✅ Filter-based routing system
- ✅ Request/response handling
- ✅ Middleware composition
- ✅ Async handler support
- ✅ Server binding and execution
Rocket ✅ COMPLETE
- ✅ Production-ready adapter implementation
- ✅ Route registration with Rocket's Handler trait
- ✅ Request/response type conversion
- ✅ Middleware integration via Fairings
- ✅ Full HTTP method support
- ✅ Server configuration and binding
- ✅ Comprehensive error handling
Salvo ✅ COMPLETE
- ✅ Production-ready adapter implementation
- ✅ High-performance web framework integration
- ✅ Modular design with extractors
- ✅ Router and Service integration
- ✅ Middleware fairing system
- ✅ Full HTTP method support
- ✅ TcpListener binding and server execution
Poem ✅ COMPLETE
- ✅ Production-ready adapter implementation
- ✅ Fast and lightweight framework integration
- ✅ Type-safe Endpoint trait implementation
- ✅ Built-in middleware (Tracing, NormalizePath)
- ✅ Comprehensive request/response conversion
- ✅ Full HTTP method support
- ✅ TcpListener and Server integration
Testing
The crate includes a mock adapter for easy testing:
#[tokio::test]
async fn test_my_routes() {
use web_server_abstraction::MockAdapter;
let server = WebServer::with_mock_adapter()
.route("/test", HttpMethod::GET, |_| async {
Ok(Response::ok().body("test"))
});
let bound_server = server.bind("127.0.0.1:0").await.unwrap();
// Mock adapter provides testing utilities
// (In practice, you'd make actual HTTP requests)
}
Run tests with:
cargo test
Run examples with:
cargo run --example basic_server
Contributing
We welcome contributions! Areas where help is needed:
- Framework Adapters: Implementing adapters for different frameworks
- Middleware: Adding common middleware implementations
- Documentation: Improving docs and examples
- Testing: Adding comprehensive test coverage
- Performance: Benchmarking and optimization
Adding a New Framework Adapter
- Create a new module in
src/adapters/ - Implement the required methods:
bind,run,route,middleware - Add conversion functions between framework types and our types
- Add a feature flag in
Cargo.toml - Update the
AdapterTypeenum incore.rs - Add tests and documentation
Performance Considerations
- Zero-cost abstractions: The abstraction layer adds minimal overhead
- Compile-time dispatch: Framework adapters use static dispatch where possible
- Memory efficiency: Minimal allocations in hot paths
- Async-first: Built for modern async Rust performance characteristics
Benchmarking and Profiling
The crate includes comprehensive benchmarking infrastructure:
use web_server_abstraction::benchmarks::{
PerformanceProfiler, BenchmarkConfig, BenchmarkSuite
};
// Configure and run performance benchmarks
let config = BenchmarkConfig {
duration: Duration::from_secs(30),
concurrent_requests: 100,
warmup_duration: Duration::from_secs(5),
};
let profiler = PerformanceProfiler::new(config);
let results = profiler.benchmark_scenario("load_test").await?;
// Analyze results with statistical metrics
println!("Average response time: {:?}", results.mean());
println!("95th percentile: {:?}", results.percentile(95.0));
println!("Requests per second: {}", results.requests_per_second());
Features include:
- Statistical Analysis: Mean, median, percentiles, standard deviation
- Memory Profiling: Memory usage tracking and leak detection
- Scenario Comparison: Compare performance across different configurations
- Optimization Recommendations: Automated performance suggestions
- Async-first: Built for modern async Rust performance characteristics
License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Roadmap
Version 0.1.0 ✅ COMPLETED
- Core abstractions and API design
- Mock adapter for testing
- Basic middleware system
- Documentation and examples
Version 0.2.0 ✅ COMPLETED
- Complete Axum adapter
- Actix-Web adapter
- Enhanced middleware ecosystem (9 middleware types implemented)
- Performance benchmarks and profiling infrastructure
Version 0.3.0 ✅ COMPLETED
- Warp adapter
- Advanced routing features (path parameters, wildcards)
- WebSocket support (basic implementation)
- HTTP method convenience functions (get, post, put, delete, patch)
- Framework adapter scaffolding (Rocket, Salvo, Poem - basic structure in place)
Version 1.0.0 ✅ COMPLETED
- Complete Rocket adapter
- Complete Salvo adapter
- Complete Poem adapter
- Comprehensive middleware library
- Production-ready performance
- Stable API
- WebSocket support
- Advanced routing features (wildcards, parameters)
- Mountable interface support
- Authentication integration## Why This Approach?
Problem Statement
Many Rust crates need to support multiple web frameworks, leading to:
- Duplicate implementation effort
- Maintenance burden across multiple framework versions
- User lock-in to specific frameworks
- Inconsistent APIs across different framework integrations
Solution Benefits
- Write Once, Run Anywhere: Implement your web logic once
- Framework Flexibility: Users can choose their preferred framework
- Easier Testing: Mock adapter makes testing straightforward
- Future-Proof: Easy to add support for new frameworks
- Consistent API: Same interface regardless of underlying framework
Trade-offs
- Additional Abstraction: One more layer between your code and the framework
- Learning Curve: New API to learn (though designed to be intuitive)
- Feature Lag: Advanced framework-specific features may not be immediately available
We believe the benefits outweigh these trade-offs for most use cases, especially for libraries and applications that need broad framework compatibility.
Dependencies
~46–88MB
~1.5M SLoC