| Crates.io | allframe |
| lib.rs | allframe |
| version | 0.1.12 |
| created_at | 2025-12-05 18:44:22.352121+00 |
| updated_at | 2025-12-15 01:36:16.37783+00 |
| description | Complete Rust web framework with built-in HTTP/2 server, REST/GraphQL/gRPC, compile-time DI, CQRS - TDD from day zero |
| homepage | https://all-source-os.github.io/all-frame |
| repository | https://github.com/all-source-os/all-frame |
| max_upload_size | |
| id | 1968957 |
| size | 1,681,168 |
The Composable Rust API Framework
One frame to rule them all. Transform, compose, ignite.
AllFrame is a complete Rust web framework with a built-in HTTP/2 server, designed and evolved exclusively through Test-Driven Development (TDD). Every feature, macro, and public API has a failing test before it is written.
AllFrame includes everything you need to build production APIs:
We ship composable crates that give you exactly what you need:
allframe ignite creates Clean Architecture projects (v0.1)allframe-mcp crate with 33 tests#[retry], #[circuit_breaker], #[rate_limited] macrosAuthenticator trait with zero dependenciesauth-jwtauth-axumauth-tonicAuthContext<C> for type-safe claims access#[derive(Obfuscate)] with #[sensitive] field attributeSensitive<T> wrapper (Debug/Display always shows "***")ShutdownAwareTaskSpawner for named tasks with automatic cancellationGracefulShutdownExt for cleanup orchestration with error handlingspawn_with_result() for tasks that return valuesShutdownExt trait for making any future cancellableallframe forge CLI (v0.6 - planned)Target: Binaries < 8 MB, > 500k req/s (TechEmpower parity with Actix), and 100% test coverage enforced by CI.
Current Status: v0.1.12 - Protocol-Agnostic Routing Complete! 455+ tests passing. Production-ready multi-protocol routing, MCP server, layered authentication, enhanced resilience (KeyedCircuitBreaker, Redis rate limiting), and safe logging! Latest: Ignite Vision - Cloud-native microservice architecture generator roadmap!
# Install AllFrame CLI
cargo install allframe
# Create a new project
allframe ignite my-api
# Run your API
cd my-api
cargo run
# Visit http://localhost:8080/swagger-ui
AllFrame includes comprehensive examples demonstrating all features:
# REST API example - Build REST APIs with AllFrame
cargo run --example rest_api
# GraphQL API example - Build GraphQL APIs with AllFrame
cargo run --example graphql_api
# gRPC API example - Build gRPC services with AllFrame
cargo run --example grpc_api
# Multi-Protocol example - Same handler, multiple protocols!
cargo run --example multi_protocol
# Resilience patterns - Retry, circuit breaker, rate limiting
cargo run --example resilience --features resilience
# Security utilities - Safe logging and obfuscation
cargo run --example security --features security
# Graceful shutdown patterns - Task spawning, cleanup, cancellation
cargo run -p allframe-core --example graceful_shutdown
cargo run -p allframe-core --example shutdown_patterns
See examples/README.md for detailed documentation.
use allframe::prelude::*;
#[di_container]
struct AppContainer {
user_repo: Arc<dyn UserRepository>,
user_service: Arc<UserService>,
}
// Dependencies resolved at compile time - zero runtime overhead
use allframe::prelude::*;
use allframe::router::{OpenApiGenerator, ScalarConfig, ScalarTheme};
// Generate OpenAPI 3.1 spec with server configuration
let spec = OpenApiGenerator::new("My API", "1.0.0")
.with_server("http://localhost:3000", Some("Development"))
.with_server("https://api.example.com", Some("Production"))
.generate(&router);
// Configure Scalar UI (10x smaller than Swagger!)
let config = ScalarConfig::new()
.theme(ScalarTheme::Dark)
.cdn_url("https://cdn.jsdelivr.net/npm/@scalar/api-reference@1.25.0")
.proxy_url("https://proxy.scalar.com"); // Enable "Try It" functionality
let html = scalar_html(&config, "My API", &spec);
// Beautiful, interactive docs at /docs
Features:
use allframe::prelude::*;
use allframe::router::{GraphiQLConfig, GraphiQLTheme, graphiql_html};
// Configure GraphiQL playground with all features
let config = GraphiQLConfig::new()
.endpoint_url("/graphql")
.subscription_url("ws://localhost:3000/graphql") // WebSocket for subscriptions
.theme(GraphiQLTheme::Dark)
.enable_explorer(true) // Interactive schema explorer
.enable_history(true) // Query history persistence
.add_header("Authorization", "Bearer your-token-here");
let html = graphiql_html(&config, "My GraphQL API");
// Beautiful, interactive GraphQL playground at /graphql/playground
Features:
See GraphQL Documentation Guide for complete setup with Axum, Actix, and Rocket.
use allframe::prelude::*;
use allframe::router::{GrpcExplorerConfig, GrpcExplorerTheme, grpc_explorer_html};
// Configure gRPC Explorer with all features
let config = GrpcExplorerConfig::new()
.server_url("http://localhost:50051")
.enable_reflection(true) // Auto-discover services
.enable_tls(false) // TLS for production
.theme(GrpcExplorerTheme::Dark)
.timeout_seconds(30)
.add_header("Authorization", "Bearer your-token-here");
let html = grpc_explorer_html(&config, "My gRPC API");
// Interactive gRPC service explorer at /grpc/explorer
Features:
See example at examples/grpc_docs.rs for complete Tonic integration.
use allframe::router::{Router, ContractTester, ContractTestConfig};
let router = Router::new();
// Simple usage - test all routes
let results = router.generate_contract_tests();
assert!(results.all_passed());
println!("Coverage: {:.1}%", results.coverage);
// Advanced usage with configuration
let tester = ContractTester::with_config(
&router,
ContractTestConfig::new()
.validate_requests(true)
.validate_responses(true)
.detect_breaking_changes(true)
.fail_fast(false)
);
let results = tester.test_all_routes();
println!("Passed: {}/{}", results.passed, results.total);
// Test specific route
let result = router.test_route_contract("/users", "GET");
assert!(result.passed);
Features:
#[handler(protocols = ["rest", "graphql", "grpc"])]
async fn create_user(input: CreateUserInput) -> Result<User, Error> {
// Same handler works as:
// - POST /users (REST)
// - mutation { createUser } (GraphQL)
// - CreateUser(request) (gRPC)
}
use allframe::prelude::*;
// Commands - 90% reduction (3 lines vs 30-40)
#[command_handler]
async fn create_user(cmd: CreateUserCommand) -> CommandResult<UserEvent> {
Ok(vec![UserEvent::Created { user_id: cmd.user_id, email: cmd.email }])
}
// Projections - 90% reduction (5 lines vs 50+)
let registry = ProjectionRegistry::new(event_store);
registry.register("users", UserProjection::new()).await;
registry.rebuild("users").await?;
// Event Versioning - 95% reduction (5 lines vs 30-40)
registry.register_upcaster(AutoUpcaster::<V1, V2>::new()).await;
// Events automatically upcasted during replay!
// Sagas - 75% reduction (20 lines vs 100+)
let saga = SagaDefinition::new("transfer")
.add_step(DebitStep { account: from, amount })
.add_step(CreditStep { account: to, amount });
orchestrator.execute(saga).await?;
// Automatic compensation on failure!
Expose your AllFrame APIs as LLM-callable tools using the Model Context Protocol.
Installation:
# Opt-in to MCP server (zero overhead if not used!)
[dependencies]
allframe = "0.1.12" # Core framework
allframe-mcp = "0.1.12" # MCP server - separate crate for zero bloat
tokio = { version = "1.48", features = ["full"] }
Quick Start:
use allframe::router::Router;
use allframe_mcp::McpServer;
#[tokio::main]
async fn main() {
// Create router with handlers
let mut router = Router::new();
router.register("get_user", |user_id: String| async move {
format!("User: {}", user_id)
});
router.register("create_order", |product: String| async move {
format!("Order created for: {}", product)
});
// Handlers automatically become LLM-callable tools!
let mcp = McpServer::new(router);
// List available tools
let tools = mcp.list_tools().await;
println!("Available tools: {}", tools.len());
// Call a tool
let result = mcp.call_tool(
"get_user",
serde_json::json!({"user_id": "123"})
).await;
}
Features:
Usage Patterns:
Documentation:
Protocol-agnostic authentication with zero-bloat feature flags:
use allframe::auth::{Authenticator, AuthError, JwtValidator, JwtConfig};
// Configure JWT validation
let config = JwtConfig::hs256("your-secret-key")
.with_issuer("your-app")
.with_audience("your-api");
let validator = JwtValidator::<MyClaims>::new(config);
// Or load from environment
let config = JwtConfig::from_env()?; // JWT_SECRET, JWT_ALGORITHM, etc.
Axum Integration:
use allframe::auth::{AuthLayer, AuthenticatedUser, JwtValidator};
// Add auth middleware
let app = Router::new()
.route("/protected", get(protected_handler))
.layer(AuthLayer::new(validator));
// Extract authenticated user in handler
async fn protected_handler(
AuthenticatedUser(claims): AuthenticatedUser<MyClaims>,
) -> String {
format!("Hello, {}!", claims.sub)
}
gRPC Integration:
use allframe::auth::{AuthInterceptor, GrpcAuthExt};
let interceptor = AuthInterceptor::new(validator);
let service = MyServiceServer::with_interceptor(impl, interceptor);
// In your gRPC handler
async fn my_method(&self, request: Request<Input>) -> Result<Response<Output>, Status> {
let claims = request.require_auth::<MyClaims>()?;
// ...
}
Features:
auth)auth-jwt)auth-axum)auth-tonic)AuthContext<C>Production-ready retry, circuit breaker, and rate limiting for robust microservices:
use allframe::resilience::{RetryConfig, RetryExecutor, CircuitBreaker, RateLimiter};
use std::time::Duration;
// Retry with exponential backoff
let config = RetryConfig::new(3)
.with_initial_interval(Duration::from_millis(100))
.with_max_interval(Duration::from_secs(5))
.with_multiplier(2.0);
let executor = RetryExecutor::new(config);
let result = executor.execute("fetch_data", || async {
external_api.fetch().await
}).await;
// Circuit breaker for fail-fast behavior
let cb = CircuitBreaker::new("payment_service", CircuitBreakerConfig::new(5));
let result = cb.call(|| async { payment_api.process().await }).await;
// Rate limiting (100 req/s with burst of 10)
let limiter = RateLimiter::new(100, 10);
if limiter.check().is_ok() {
handle_request().await;
}
Or use attribute macros:
use allframe::{retry, circuit_breaker, rate_limited};
#[retry(max_retries = 3, initial_interval_ms = 100)]
async fn fetch_user(id: &str) -> Result<User, Error> {
api.get_user(id).await // Automatically retried!
}
#[circuit_breaker(failure_threshold = 5, timeout_secs = 30)]
async fn call_payment() -> Result<Payment, Error> {
payment_api.process().await // Fails fast when circuit is open!
}
Features:
Safe logging utilities to prevent credential leaks:
use allframe::security::{obfuscate_url, obfuscate_api_key, Sensitive};
use allframe::Obfuscate;
use allframe::security::Obfuscate as ObfuscateTrait;
// URL obfuscation
let url = "https://user:pass@api.example.com/v1/users?token=secret";
println!("Connecting to: {}", obfuscate_url(url));
// Output: "https://api.example.com/***"
// API key obfuscation
let key = "sk_live_1234567890abcdef";
println!("Using key: {}", obfuscate_api_key(key));
// Output: "sk_l***cdef"
// Sensitive wrapper (Debug/Display always shows ***)
let password = Sensitive::new("super_secret");
println!("{:?}", password); // Output: Sensitive(***)
// Derive macro for structs
#[derive(Obfuscate)]
struct DbConfig {
host: String,
#[sensitive]
password: String,
}
let config = DbConfig { host: "db.example.com".into(), password: "secret".into() };
println!("{}", config.obfuscate());
// Output: DbConfig { host: "db.example.com", password: *** }
Features:
Sensitive<T> wrapper type#[derive(Obfuscate)] with #[sensitive] fields| Feature | AllFrame | Actix | Axum | Rocket |
|---|---|---|---|---|
| TDD-First | ✅ 100% | ❌ | ❌ | ❌ |
| Compile-time DI | ✅ | ❌ | ❌ | ❌ |
| Auto OpenAPI 3.1 | ✅ | 🟡 Manual | 🟡 Manual | 🟡 Manual |
| CQRS + Event Sourcing | ✅ Built-in | ❌ | ❌ | ❌ |
| CommandBus | ✅ 90% less code | ❌ | ❌ | ❌ |
| Saga Orchestration | ✅ Auto compensation | ❌ | ❌ | ❌ |
| Resilience Patterns | ✅ Built-in | 🟡 External | 🟡 External | ❌ |
| Layered Auth | ✅ Protocol-agnostic | 🟡 External | 🟡 External | 🟡 External |
| Safe Logging | ✅ Built-in | ❌ | ❌ | ❌ |
| Protocol-agnostic | ✅ | ❌ | ❌ | ❌ |
| MCP Server | ✅ Zero Bloat | ❌ | ❌ | ❌ |
| Zero runtime deps | ✅ | ❌ | ✅ | ❌ |
| Binary size | < 8 MB | ~12 MB | ~6 MB | ~10 MB |
[dependencies]
allframe = "0.1.12"
cargo install allframe
use allframe::prelude::*;
#[allframe::main]
async fn main() {
let app = App::new()
.route("/hello", get(hello_handler));
app.run().await;
}
#[api_handler]
async fn hello_handler() -> &'static str {
"Hello, AllFrame!"
}
Run:
cargo run
OpenAPI docs automatically available at:
AllFrame uses Cargo feature flags to minimize bloat - you only pay for what you use:
[dependencies]
allframe = { version = "0.1.12", features = ["di", "openapi"] }
| Feature | Description | Binary Impact | Default |
|---|---|---|---|
di |
Compile-time dependency injection | +0KB | ✅ |
openapi |
Auto OpenAPI 3.1 + Swagger UI | +0KB | ✅ |
router |
Protocol-agnostic routing + TOML config | +50KB | ✅ |
| Feature | Description | Binary Impact | Default |
|---|---|---|---|
router-graphql |
Production GraphQL (async-graphql, GraphiQL) | +2MB | ❌ |
router-grpc |
Production gRPC (tonic, streaming, reflection) | +3MB | ❌ |
router-full |
Both GraphQL + gRPC production adapters | +5MB | ❌ |
resilience |
Retry, circuit breaker, rate limiting | +120KB | ❌ |
resilience-keyed |
KeyedCircuitBreaker for per-resource isolation | +10KB | ❌ |
resilience-redis |
Redis-backed distributed rate limiting | +50KB | ❌ |
auth |
Core authentication traits (zero deps) | +5KB | ❌ |
auth-jwt |
JWT validation (HS256, RS256, EdDSA) | +80KB | ❌ |
auth-axum |
Axum extractors and middleware | +20KB | ❌ |
auth-tonic |
gRPC interceptors | +15KB | ❌ |
security |
Safe logging, obfuscation utilities | +30KB | ❌ |
| Feature | Description | Reduction | Default |
|---|---|---|---|
cqrs |
CQRS + Event Sourcing infrastructure | 85% avg | ✅ |
cqrs-allsource |
AllSource backend (embedded DB) | - | ❌ |
cqrs-postgres |
PostgreSQL backend (planned) | - | ❌ |
cqrs-rocksdb |
RocksDB backend (planned) | - | ❌ |
What you get:
MCP (Model Context Protocol) is now a separate crate for 100% zero bloat:
# Only add if you need LLM integration
[dependencies]
allframe-mcp = "0.1.12"
Benefits:
See MCP Zero-Bloat Strategy for details.
💡 Tip: Start minimal and add features as needed. See docs/feature-flags.md for detailed guidance.
Minimal REST API:
allframe = { version = "0.1.12", default-features = false, features = ["router"] }
Production GraphQL API:
allframe = { version = "0.1.12", features = ["router-graphql"] }
Multi-Protocol Gateway:
allframe = { version = "0.1.12", features = ["router-full"] }
AllFrame is 100% TDD-driven. Before contributing:
Every commit must contain at least one new failing test.
# Clone the repo
git clone https://github.com/all-source-os/all-frame.git
cd all-frame
# Run tests (must pass)
cargo test
# Check coverage (must be 100%)
cargo llvm-cov
# Run quality checks
cargo clippy -- -D warnings
cargo fmt -- --check
See CONTRIBUTING.md for detailed guidelines. (coming soon)
AllFrame is evolving into a cloud-native microservice architecture generator.
See ROADMAP.md for the complete vision and Project Status for current progress.
Vision: Generate deployable microservice architectures from declarative configuration:
# Today
allframe ignite my-project
# Tomorrow (v0.5+)
allframe ignite --config architecture.toml
# Generates complete microservice architecture with Terraform/Pulumi IaC
Phase 6.4: gRPC Documentation ✅ (Dec 2025)
Phase 6.3: GraphQL Documentation ✅ (Dec 2025)
Track A: Scalar Integration ✅ (Dec 2025)
Track B: Binary Size Monitoring ✅ (Dec 2025)
Phases 1-5: CQRS Infrastructure ✅ (Nov 2025)
v0.0 - Repository setup, documentation migration ✅
v0.1 - allframe ignite + hello world ✅
v0.2 - Compile-time DI + OpenAPI ✅
v0.3 - OpenTelemetry tracing ✅
Next Up: LLM Integration & Code Generation
allframe forge CLI (v0.6)Performance & Ecosystem
Advanced Features
Production Hardening
Read the full roadmap → | View Ignite Vision →
We do not write a single line of implementation until a test fails for it.
// 1. RED - Write failing test
#[test]
fn test_user_creation() {
let user = User::new("test@example.com");
assert!(user.is_ok());
}
// 2. GREEN - Minimal implementation
pub struct User { email: String }
impl User {
pub fn new(email: impl Into<String>) -> Result<Self, Error> {
Ok(Self { email: email.into() })
}
}
// 3. REFACTOR - Improve while keeping tests passing
AllFrame only depends on:
No hidden bloat. No dependency hell.
Dependencies flow inward only:
Presentation → Application → Domain ← Infrastructure
This is enforced at compile time by AllFrame's macros.
AllFrame targets TechEmpower Round 23 benchmarks in future releases:
| Metric | Target | Status |
|---|---|---|
| JSON serialization | > 500k req/s | 📋 Planned |
| Single query | > 100k req/s | 📋 Planned |
| Multiple queries | > 50k req/s | 📋 Planned |
| Binary size | < 8 MB | ✅ Achieved (<2 MB) |
Note: Performance benchmarking is planned for Q2 2025. Current focus is on feature completeness and correctness. All functionality is production-ready with comprehensive test coverage (450+ tests passing).
Licensed under either of:
at your option.
AllFrame is inspired by:
AllFrame. One frame. Infinite transformations.
Built with TDD, from day zero.