Skip to content

Latest commit

History

467 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Hiver Framework

Hiver is an alpha-stage web framework written in Rust with a custom async runtime, aiming to mirror the Spring ecosystem. Unlike other frameworks that use Tokio, Hiver features a custom async runtime built from scratch using io-uring for maximum performance. Not yet production-ready (0.1.0-alpha.6) — see project status.

🎯 Features

  • Custom Runtime - Thread-per-core architecture with io-uring support
  • Spring-like Annotations - #[controller], #[service], #[repository], #[autowired], #[transactional], @Cacheable, @PreAuthorize, and 40+ more
  • Data Layer - R2DBC, ORM (ActiveRecord), Redis, MongoDB, Flyway migrations, JPA-style #[Entity]/#[Table]/#[Id]/#[Column]
  • AI Integration - OpenAI, Anthropic, Ollama chat models; embeddings; vector store; function calling
  • Messaging - Kafka, AMQP/RabbitMQ, Spring Events, Spring Integration EIP patterns
  • Cloud - Service discovery, load balancer, gateway, config server, Feign client
  • Security - JWT, OAuth2 Authorization Server, RBAC, CSRF, @PreAuthorize, @Secured
  • High Availability - Circuit breakers, rate limiters, retry logic
  • Web3 Native - Built-in blockchain and smart contract support (ERC20/ERC721)
  • Observability - Distributed tracing, Micrometer-compatible metrics, OpenAPI/Swagger
  • Enterprise - Batch processing, state machine, LDAP, Vault, SOAP WS, GraphQL, gRPC, i18n
  • Tooling - Lombok-style derive macros, Spring Shell REPL, test containers, mock beans

⚡️ Quick Start

Installation

Add to your Cargo.toml:

[dependencies]
# Published to crates.io (0.1.0-alpha.6)# 已发布到 crates.io(0.1.0-alpha.6)hiver-runtime = "0.1.0-alpha.6"hiver-http = { version = "0.1.0-alpha.6", features = ["full"] }
hiver-router = "0.1.0-alpha.6"hiver-observability = "0.1.0-alpha.6"

Basic HTTP Server

use hiver_http::{Body,Response,Server,StatusCode};use hiver_runtime::Runtime;fnmain() -> Result<(),Box<dyn std::error::Error>>{// Initialize logging
tracing_subscriber::fmt().with_max_level(tracing::Level::INFO).init();// Create runtime and run serverletmut runtime = Runtime::new()?;
runtime.block_on(async{// Bind server to addresslet _server = Server::bind("127.0.0.1:8080").run(handle_request).await?;Ok::<_,Box<dyn std::error::Error>>(())})}asyncfnhandle_request(req: hiver_http::Request) -> Result<Response, hiver_http::Error>{Ok(Response::builder().status(StatusCode::OK).header("content-type","text/plain").body(Body::from("Hello, Hiver!")).unwrap())}

Complete REST API Example

//! Hiver REST API Example//!//! This example demonstrates a complete REST API with://! - Routing with path parameters//! - JSON request/response//! - Error handling//! - Middleware (CORS, logging)//! - Circuit breaker//! - Observability (tracing, metrics)use hiver_http::{Body,Response,Server,StatusCode,Request,ResultasHttpResult,};use hiver_router::Router;use hiver_runtime::Runtime;use hiver_observability::{tracing, metrics};// ============================================================================// Data Models// ============================================================================/// User representation#[derive(Debug,Clone, serde::Serialize, serde::Deserialize)]structUser{id:u64,username:String,email:String,}/// Create user request#[derive(Debug, serde::Deserialize)]structCreateUserRequest{username:String,email:String,}// ============================================================================// Error Handling// ============================================================================/// API Error type#[derive(Debug)]enumApiError{/// User not found (404)UserNotFound(u64),/// Invalid input (400)InvalidInput(String),/// Internal server error (500)Internal(String),}implApiError{/// Convert to HTTP status codefnstatus_code(&self) -> StatusCode{matchself{ApiError::UserNotFound(_) => StatusCode::NOT_FOUND,ApiError::InvalidInput(_) => StatusCode::BAD_REQUEST,ApiError::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR,}}/// Get error messagefnmessage(&self) -> String{matchself{ApiError::UserNotFound(id) => format!("User {} not found", id),ApiError::InvalidInput(msg) => msg.clone(),ApiError::Internal(msg) => format!("Internal error: {}", msg),}}}// ============================================================================// In-Memory Store// ============================================================================/// Simple in-memory user storestructUserStore{users: std::sync::Arc<parking_lot::Mutex<std::collections::HashMap<u64,User>>>,next_id: std::sync::Arc<std::sync::atomic::AtomicU64>,}implUserStore{/// Create new storefnnew() -> Self{Self{users: std::sync::Arc::new(parking_lot::Mutex::new(std::collections::HashMap::new())),next_id: std::sync::Arc::new(std::sync::atomic::AtomicU64::new(1)),}}/// Get user by IDfnget(&self,id:u64) -> Option<User>{self.users.lock().get(&id).cloned()}/// Create new userfncreate(&self,req:CreateUserRequest) -> User{let id = self.next_id.fetch_add(1, std::sync::atomic::Ordering::SeqCst);let user = User{
id,username: req.username,email: req.email,};self.users.lock().insert(id, user.clone());
user
}/// List all usersfnlist(&self) -> Vec<User>{self.users.lock().values().cloned().collect()}}// ============================================================================// Route Handlers// ============================================================================/// GET /users - List all usersasyncfnlist_users(_req:Request,store: hiver_router::State<UserStore>,) -> HttpResult<Response>{
tracing::info!("Listing all users");let users = store.list();Ok(Response::builder().status(StatusCode::OK).header("content-type","application/json").body(Body::from(serde_json::to_string(&users).unwrap())).unwrap())}/// GET /users/:id - Get user by IDasyncfnget_user(req:Request,store: hiver_router::State<UserStore>,) -> HttpResult<Response>{// Extract path parameterlet id = req
.param("id").and_then(|s| s.parse::<u64>().ok()).ok_or_else(|| ApiError::InvalidInput("Invalid user ID".to_string()))?;
tracing::info!("Getting user: {}", id);// Look up userlet user = store
.get(id).ok_or_else(|| ApiError::UserNotFound(id))?;Ok(Response::builder().status(StatusCode::OK).header("content-type","application/json").body(Body::from(serde_json::to_string(&user).unwrap())).unwrap())}/// POST /users - Create new userasyncfncreate_user(mutreq:Request,store: hiver_router::State<UserStore>,) -> HttpResult<Response>{// Parse request bodylet body = std::pin::pin(&mut req).body_bytes().await.map_err(|e| ApiError::Internal(format!("Failed to read body: {}", e)))?;let create_req = serde_json::from_slice::<CreateUserRequest>(&body).map_err(|e| ApiError::InvalidInput(format!("Invalid JSON: {}", e)))?;
tracing::info!("Creating user: {}", create_req.username);// Validate inputif create_req.username.is_empty() || create_req.username.len() > 50{returnErr(ApiError::InvalidInput("Username must be 1-50 characters".into()).into());}// Create userlet user = store.create(create_req);Ok(Response::builder().status(StatusCode::CREATED).header("content-type","application/json").header("location",format!("/users/{}", user.id)).body(Body::from(serde_json::to_string(&user).unwrap())).unwrap())}// ============================================================================// Error Conversion// ============================================================================implFrom<ApiError>for hiver_http::Error{fnfrom(err:ApiError) -> Self{
hiver_http::Error::new(err.status_code(), err.message())}}// ============================================================================// Main Application// ============================================================================fnmain() -> Result<(),Box<dyn std::error::Error>>{// Initialize logging
tracing_subscriber::fmt().with_max_level(tracing::Level::INFO).init();// Create shared statelet store = UserStore::new();// Build routerlet app = Router::new()// GET /users - List users.route("/users", hiver_router::Method::GET, list_users)// GET /users/:id - Get user.route("/users/:id", hiver_router::Method::GET, get_user)// POST /users - Create user.route("/users", hiver_router::Method::POST, create_user)// Add state.with_state(store);// Create and run runtimeletmut runtime = Runtime::new()?;
tracing::info!("Starting server on http://127.0.0.1:8080");
runtime.block_on(async{// Start serverlet _server = Server::bind("127.0.0.1:8080").run(app).await?;Ok::<_,Box<dyn std::error::Error>>(())})}

Testing the API

# List users (empty)
curl http://localhost:8080/users
# Create a user
curl -X POST http://localhost:8080/users \
-H "Content-Type: application/json" \
-d '{"username":"alice","email":"alice@example.com"}'# Get user by ID
curl http://localhost:8080/users/1
# List users (with data)
curl http://localhost:8080/users

Hiver Logging

Hiver provides a unified logging system with two modes: Verbose (development) and Simple (production).

use hiver_observability::log::{Logger,LoggerConfig,LogLevel,LogMode};fnmain() -> Result<(),Box<dyn std::error::Error>>{// Automatic mode selection based on profilelet config = LoggerConfig{level:LogLevel::Info,mode:LogMode::from_profile(Some("dev")),// dev->Verbose, prod->Simple
..Default::default()};Logger::init_with_config(config)?;
tracing::info!("Application started");Ok(())}

Configuration via Environment Variables:

# Set log levelexport HIVER_LOG_LEVEL=DEBUG
# Set log mode explicitlyexport HIVER_LOG_MODE=simple # or "verbose"# Set profile (affects default mode)export HIVER_PROFILE=prod # dev->verbose, prod->simple

Output Comparison:

ModeFormat
Verbose (dev)2026-01-30 10:30:45.123 |INFO| 55377 [main] n.http.server : Request received
Simple (prod)INFO n.http.server: Request received

Resilience Patterns

use hiver_resilience::{CircuitBreaker,RateLimiter,RetryPolicy};use hiver_http::Request;// Circuit breakerlet breaker = CircuitBreaker::new("external-api",5,// failure threshold10000,// timeout ms);// Rate limiterlet limiter = RateLimiter::token_bucket(100,10);// 100 requests, refill 10/sec// Retry with exponential backofflet retry = RetryPolicy::exponential_backoff(3,100);// 3 retries, 100ms base// Use in handlerasyncfncall_external_api(req:Request) -> Result<Response,Error>{
breaker.call(|| async{
limiter.throttle().await?;
retry.retry(|| async{// Actual API callmake_request(req).await}).await}).await}

Web3 Support

use hiver_web3::{Chain,ChainConfig,LocalWallet,RpcClient,Transaction,TransactionBuilder,TxType,};asyncfnweb3_example() -> Result<(),Box<dyn std::error::Error>>{// Connect to Ethereumlet chain = Chain::ethereum();let rpc = RpcClient::new(&chain.rpc_url())?;// Create walletlet wallet = LocalWallet::new(&mut rand::thread_rng());// Build transactionlet tx = TransactionBuilder::new().to(wallet.address()).value(1000000)// 0.001 ETH.gas_limit(21000).chain_id(chain.chain_id()).build(TxType::Legacy)?;// Send transactionlet signed = wallet.sign_transaction(&tx)?;let tx_hash = rpc.send_raw_transaction(&signed).await?;
tracing::info!("Transaction sent: {}", tx_hash);Ok(())}

🚀 Performance

Hiver is designed for high performance from the ground up:

  • 70% fewer syscalls vs epoll with io-uring
  • 40% lower latency with thread-per-core architecture
  • Zero-copy I/O for minimal allocations
  • Linear scalability with no lock contention
BenchmarkResult
HTTP Parsing (GET)~170 ns
HTTP Encoding~120 ns
Throughput6.8 GiB/s
Spawn latency< 1 μs
Channel throughput10M+ msg/s

📚 Documentation

ResourceLink
CodemapCODEMAP.md — Full crate reference, macro index, dependency graph
Bookdocs.hiverframework.com
API Docsdocs.rs/hiver
Design Specdesign-spec.md
Spring ComparisonSPRING-COMPARISON.md — Spring vs Hiver ecosystem comparison
Implementation Planimplementation-plan.md
Docs IndexDOCS-INDEX.md
Examplesexamples/

🏗️ Architecture

62 crates across 10 functional domains. See CODEMAP.md for the full reference.

hiver-starter (Spring Boot auto-configuration)
│
├── Web: hiver-http, hiver-router, hiver-extractors, hiver-middleware,
│ hiver-response, hiver-hateoas, hiver-multipart, hiver-openapi, hiver-graphql
├── Data: hiver-data-commons, hiver-data-rdbc, hiver-data-orm, hiver-data-redis,
│ hiver-data-mongodb, hiver-data-annotations, hiver-data-macros, hiver-flyway
├── Security: hiver-security, hiver-session
├── AOP: hiver-aop, hiver-tx
├── Messaging:hiver-events, hiver-events-macros, hiver-kafka, hiver-amqp,
│ hiver-integration, hiver-websocket-stomp
├── Infra: hiver-runtime, hiver-core, hiver-macros, hiver-lombok, hiver-config,
│ hiver-exceptions, hiver-spel
├── Cloud: hiver-cloud, hiver-ai, hiver-agent, hiver-web3, hiver-vault, hiver-ldap, hiver-grpc
├── Resilience:hiver-resilience, hiver-observability, hiver-micrometer, hiver-actuator,
│ hiver-retry, hiver-retry-macros
├── Enterprise:hiver-batch, hiver-state-machine, hiver-async, hiver-schedule, hiver-ws,
│ hiver-i18n, hiver-modulith
└── Tooling: hiver-test, hiver-shell, hiver-shell-macros, hiver-benches, hiver-validation,
hiver-validation-annotations, hiver-cache

🛠️ Development

# Clone repository
git clone https://github.com/ViewWay/hiver.git
cd hiver
# Build
cargo build --workspace
# Test
cargo test --workspace
# Run benchmarks
cargo bench -p hiver-runtime
# Format
cargo fmt --all
# Lint
cargo clippy --workspace -- -D warnings

📋 Project Status

⚠️ Alpha Version

Hiver is alpha software (0.1.0-alpha.6). Currently in Phase 8: Data Layer (in progress). Phases 0–7 feature work is done (code-level), but not production-stable. The custom async runtime is stable under cargo test --workspace (4 UBs fixed, Phase 0.1 complete). The framework spans 70 crates covering the Spring Boot feature surface. See verified gap report and roadmap.

PhaseStatusDescription
Phase 0✅ CompleteFoundation
Phase 1✅ CompleteRuntime Core
Phase 2✅ CompleteHTTP Server
Phase 3✅ CompleteRouter & Middleware
Phase 4✅ CompleteResilience
Phase 5✅ CompleteObservability
Phase 6✅ CompleteWeb3 Integration
Phase 7✅ CompletePerformance & Hardening
Phase 8🔄 In ProgressData Layer (R2DBC, ORM, Redis, MongoDB, Flyway) — 8.1–8.3 core modules complete, structural refactoring ongoing

See implementation plan for details.

🤝 Contributing

We welcome contributions! Please see CONTRIBUTING.md for guidelines.

📄 License

Hiver is licensed under either of

🙏 Acknowledgments

Hiver is inspired by excellent frameworks across multiple languages:

  • Rust: Axum, Actix Web, Monoio, Salvo
  • Go: Gin, Echo
  • Java: Spring Boot, WebFlux
  • Python: FastAPI, Starlette

Hiver Framework — Built for the future of web development.

About

A production-grade, high-availability web framework written in Rust.

Resources

Contributing

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages