buzzard

Crates.iobuzzard
lib.rsbuzzard
version0.1.0
created_at2025-07-20 13:05:28.501811+00
updated_at2025-07-20 13:05:28.501811+00
descriptionA lightweight, DDD-first message bus framework for Rust β€” orchestrate commands, events, and projections with confidence.
homepage
repositoryhttps://github.com/award28/buzzard
max_upload_size
id1761044
size46,558
Austin Ward (award28)

documentation

README

πŸ¦… buzzard

A lightweight, DDD-first message bus framework for Rust β€” orchestrate commands, events, and projections with confidence.


buzzard is a strongly typed, domain-driven orchestration framework for message-based applications in Rust. Inspired by hexagonal and DDD patterns, it lets you model business flows with explicit Command, Event, and Projection types while remaining infrastructure-agnostic.


✨ Features

  • 🧠 Domain-driven: Clean separation of Commands, Events, and Projections
  • πŸ”„ Fully asynchronous and Send + Sync + Clone safe
  • πŸ“¦ Broker-agnostic (Redis, Postgres, NATS, etc.)
  • 🧱 Extensible via MessageBusDriver, CommandHandler, Policy, and Projector
  • πŸš€ Easy to integrate into web servers, CLI apps, and background workers

πŸ“¦ Quickstart Example

#[tokio::main]
async fn main() -> Result<()> {
    let driver = MyDriver::init().await?;
    let bus = MessageBus::from(&driver);

    // Run bus in the background
    let background = tokio::spawn(bus.clone().start());

    // Dispatch a command from a web handler, CLI, etc.
    let cmd = MyCommand { sku: "ABC-123".into() };
    let response = bus.dispatch(cmd).await?;

    background.await??;
    Ok(())
}

🧠 Message Flow

                            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                            β”‚      Message Bus       β”‚
                            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                         β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚                                β”‚                                β”‚
        β–Ό                                β–Ό                                β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”             β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Command Msg   β”‚              β”‚    Event Msg        β”‚             β”‚ Projection Msg     β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚                                 β”‚                                    β”‚
       β–Ό                                 β–Ό                                    β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”             β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ CommandHandlerβ”‚              β”‚      Policy        β”‚             β”‚       Projector        β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚ domain mutation                β”‚ maps event to side effects          β”‚
       β–Ό                                β–Ό                                     β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                    β”‚
β”‚     UnitOfWork     β”‚      β”‚ Vec<SideEffect<Cmd, Proj>> β”‚                    β”‚
β”‚ - apply mutations  β”‚      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                    β”‚
β”‚ - capture events   β”‚                    β”‚                                   β”‚
β”‚ - commit/rollback  β”‚                    β”‚                                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                    β”‚                                   β”‚
          β”‚ commits                       β”‚ publishes                         β”‚
          β–Ό                               β–Ό                                   β–Ό
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚ Event Msg(s) │───────►│ Message Bus (loopback)     β”‚         β”‚ Projection Msgs from Policy β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“š Traits You Implement

Trait Description
MessageBusDriver Declares domain types + infrastructure
CommandHandler Executes domain logic with mutation
Policy Reacts to events with follow-up messages
Projector Handles read model and infra updates

πŸ”„ Lifecycle Summary

  1. dispatch(command) β†’ handled in UnitOfWork
  2. Domain events are emitted and published
  3. Events trigger Policy logic β†’ follow-up messages
  4. Messages include new commands or projections
  5. Projections handled by external-side Projector

βœ… When to Use

  • You want a clean, extensible message-processing runtime
  • You use DDD / CQRS and want to model each message explicitly
  • You want to test your business logic independently of infrastructure

πŸ”— Built With

  • futures, anyhow
  • Your backend: PostgreSQL, Redis, NATS, MeiliSearch...
Commit count: 0

cargo fmt