RabbitMesh Macros - The Magic Behind Zero-Port Microservices ✨
Procedural macros that transform simple Rust structs into complete microservices with automatic route generation and RabbitMQ RPC integration.
This crate provides the three core macros that make RabbitMesh's zero-configuration philosophy possible:
#[service_definition]
- Marks a struct as a RabbitMesh service
#[service_impl]
- Processes impl blocks to auto-register methods
#[service_method]
- Defines HTTP routes and RPC handlers
🪄 The Magic
Write this simple code:
use rabbitmesh_macros::{service_definition, service_impl};
use serde::{Deserialize, Serialize};
#[derive(Deserialize)]
pub struct CreateUserRequest {
pub name: String,
pub email: String,
}
#[derive(Serialize)]
pub struct UserResponse {
pub success: bool,
pub message: String,
pub user_id: Option<String>,
}
#[service_definition]
pub struct UserService;
#[service_impl]
impl UserService {
#[service_method("POST /users")]
pub async fn create_user(request: CreateUserRequest) -> Result<UserResponse, String> {
println!("Creating user: {}", request.name);
Ok(UserResponse {
success: true,
message: "User created successfully".to_string(),
user_id: Some("user123".to_string()),
})
}
#[service_method("GET /users/:id")]
pub async fn get_user(user_id: String) -> Result<UserResponse, String> {
println!("Getting user: {}", user_id);
Ok(UserResponse {
success: true,
message: format!("Retrieved user {}", user_id),
user_id: Some(user_id),
})
}
}
And get all this automatically generated:
- ✅ HTTP routes:
POST /users
, GET /users/:id
- ✅ RabbitMQ RPC handlers:
rabbitmesh.UserService.create_user
, rabbitmesh.UserService.get_user
- ✅ Service registration methods:
UserService::create_service()
, UserService::service_name()
- ✅ Route discovery:
UserService::get_routes()
- ✅ JSON serialization/deserialization
- ✅ API Gateway integration
- ✅ Service discovery
🎯 Supported Method Patterns
The macros intelligently handle different method signatures:
# use rabbitmesh_macros::{service_definition, service_impl};
# use serde::{Deserialize, Serialize};
# #[derive(Deserialize)] pub struct CreateRequest { pub name: String }
# #[derive(Deserialize)] pub struct UpdateRequest { pub name: String }
# #[derive(Serialize)] pub struct Response { pub success: bool }
# #[service_definition] pub struct MyService;
#[service_impl]
impl MyService {
#[service_method("GET /items/:id")]
async fn get_item(id: String) -> Result<Response, String> {
Ok(Response { success: true })
}
#[service_method("POST /items")]
async fn create_item(request: CreateRequest) -> Result<Response, String> {
Ok(Response { success: true })
}
#[service_method("PUT /items/:id")]
async fn update_item(params: (String, UpdateRequest)) -> Result<Response, String> {
let (id, request) = params;
Ok(Response { success: true })
}
#[service_method("GET /users/:user_id/items/:item_id")]
async fn get_user_item(params: (String, String)) -> Result<Response, String> {
let (user_id, item_id) = params;
Ok(Response { success: true })
}
}