Expand description
Β§RabbitMesh - Zero-Port Microservices Framework
Build elegant microservices with simple macros - write only business logic!
RabbitMesh revolutionizes microservices by eliminating port management through pure RabbitMQ communication. Services are defined with clean Rust macros, and everything else is auto-generated.
Β§β¨ The Magic
use rabbitmesh_macros::{service_definition, service_impl};
use serde::{Deserialize, Serialize};
#[derive(Deserialize)]
pub struct CreateUserRequest {
pub username: String,
pub email: String,
}
#[derive(Serialize)]
pub struct UserResponse {
pub success: bool,
pub message: String,
}
// Define your service with macros
#[service_definition]
pub struct UserService;
// Implement business logic only - framework handles everything else!
#[service_impl]
impl UserService {
#[service_method("POST /users")]
pub async fn create_user(request: CreateUserRequest) -> Result<UserResponse, String> {
// JUST YOUR BUSINESS LOGIC!
// Framework automatically handles:
// β
HTTP route extraction (POST /users)
// β
RabbitMQ RPC registration
// β
JSON serialization/deserialization
// β
API Gateway integration
// β
Service discovery
println!("Creating user: {}", request.username);
Ok(UserResponse {
success: true,
message: "User created successfully!".to_string(),
})
}
#[service_method("GET /users/:id")]
pub async fn get_user(user_id: String) -> Result<UserResponse, String> {
// Framework auto-extracts 'user_id' from URL path
println!("Getting user: {}", user_id);
Ok(UserResponse {
success: true,
message: format!("Retrieved user {}", user_id),
})
}
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Initialize service (for stateful services)
// UserService::init().await?;
// Create and start service - that's it!
let service = UserService::create_service("amqp://guest:guest@localhost:5672/%2f").await?;
println!("π UserService started!");
println!("π― Service name: {}", UserService::service_name());
// Show the magic - auto-discovered routes
let routes = UserService::get_routes();
println!("β¨ Auto-discovered {} routes:", routes.len());
for (route, method) in routes {
println!(" {} -> {}", method, route);
}
service.start().await?;
Ok(())
}
Β§πͺ What RabbitMesh Does Automatically
When you write #[service_method("POST /users")]
, the framework automatically:
- β
Extracts HTTP route from annotation (
POST /users
) - β
Registers RPC handler for the method (
create_user
) - β
Sets up RabbitMQ queues (
rabbitmesh.UserService.create_user
) - β Handles serialization (JSON request/response)
- β Creates gateway endpoint (HTTP API automatically available)
- β Enables service discovery (other services can call this method)
- β Provides health checks and monitoring
- β Implements fault tolerance (retries, circuit breakers)
You write: 5-10 lines of business logic
Framework provides: Everything else (hundreds of lines worth!)
Β§ποΈ Zero-Port Architecture
Traditional Microservices:
Service A:8080 βHTTPβ Service B:8081 βHTTPβ Service C:8082
β Port management hell
β Service discovery complexity
β Load balancing configuration
RabbitMesh:
Service A βRabbitMQβ Service B βRabbitMQβ Service C
β β β
Auto-Generated Gateway:3000 βHTTPβ Clients
β
Zero port management between services
β
Automatic service discovery
β
Built-in load balancing and fault tolerance
Β§π¨ Method Signature Patterns
RabbitMesh supports clean, intuitive method signatures:
#[service_impl]
impl UserService {
// Simple parameter
#[service_method("GET /users/:id")]
async fn get_user(user_id: String) -> Result<UserResponse, String> {
// user_id auto-extracted from URL path
Ok(UserResponse { success: true })
}
// Request body
#[service_method("POST /users")]
async fn create_user(request: CreateUserRequest) -> Result<UserResponse, String> {
// request auto-deserialized from JSON
Ok(UserResponse { success: true })
}
// Path parameter + request body (tuple)
#[service_method("PUT /users/:id")]
async fn update_user(params: (String, UpdateUserRequest)) -> Result<UserResponse, String> {
let (user_id, request) = params;
Ok(UserResponse { success: true })
}
// Multiple path parameters
#[service_method("GET /users/:user_id/posts/:post_id")]
async fn get_user_post(params: (String, String)) -> Result<UserResponse, String> {
let (user_id, post_id) = params;
Ok(UserResponse { success: true })
}
}
Β§π Service-to-Service Communication
Services communicate via RabbitMQ automatically:
use rabbitmesh::ServiceClient;
// From API Gateway or another service
let client = ServiceClient::new("api-gateway", "amqp://localhost:5672").await?;
let response = client.call("user-service", "get_user", "user123").await?;
Β§π― Key Features
- πͺ Zero Configuration: Routes extracted from code annotations
- π Auto-Generated Gateway: HTTP API created from service definitions
- π Zero Ports: Services communicate only via RabbitMQ
- π Auto-Discovery: Services find each other automatically
- β‘ High Performance: Built on Tokio async runtime
- π‘οΈ Fault Tolerance: Built-in retry mechanisms and circuit breakers
- π Observability: Structured logging and health checks
- π¨ Clean Code: Write only business logic, framework handles the rest
Β§π Examples
See the examples/
directory for complete working examples:
- Simple Todo Service: Basic CRUD operations with auto-generated routes
- Authentication Service: JWT tokens, user management, password hashing
- Blog Platform: Multi-service architecture with auto-discovery
Β§π€ AI Assistant
Get help building services with our AI agent:
python rabbitmesh_agent.py "build me an authentication service"
Β§π§ͺ Requirements
- Rust: 1.70+
- RabbitMQ: 3.8+
- Dependencies:
rabbitmesh-macros
,serde
,tokio
Ready to build the future of microservices? π
Zero ports, maximum power, pure elegance.
Re-exportsΒ§
pub use connection::ConnectionManager;
pub use connection::ConnectionConfig;
pub use message::Message;
pub use message::MessageType;
pub use message::RpcRequest;
pub use message::RpcResponse;
pub use rpc::RpcHandler;
pub use rpc::RpcFramework;
pub use service::MicroService;
pub use service::ServiceConfig;
pub use service::ServiceClient as ServiceClientFromService;
pub use service::MicroService as Service;
pub use client::ServiceClient;
pub use error::RabbitMeshError;
pub use error::Result;