ruststream 0.2.5

Async messaging framework for Rust: broker-agnostic traits, router, codecs, and a conformance harness for broker authors.
Documentation

RustStream connects your service to a message broker through a small set of generic traits, then gives you a router, middleware, codecs, and tooling on top. The core depends on no broker, so each broker is an independent crate held to one contract; broker-specific configuration never leaks into the framework.

Features

  • Broker-agnostic core. Just traits and types, zero broker dependencies. Brokers are separate crates, and the contract is checked by a conformance harness.
  • Fully async on tokio. No blocking APIs in the public surface.
  • Subscribers are Streams, not callbacks. Back-pressure comes for free.
  • Ack consumes self. Double-ack is a compile error.
  • Pluggable codecs: JSON, MessagePack, and CBOR behind cargo features.
  • Zero-boilerplate binaries. #[ruststream::app] generates main; the ruststream CLI scaffolds projects, runs them, and generates the AsyncAPI document.
  • AsyncAPI 3.0 and Prometheus metrics, served from your own HTTP stack.
  • Colored console logging behind the logging feature; the generated CLI installs it on run, with verbosity driven by RUST_LOG.
  • Capability traits for optional features (batch subscribe, transactions, request-reply, partitioning); a broker implements only what it supports.

Install

[dependencies]
ruststream = { version = "0.2", features = ["macros", "memory", "json"] }
serde = { version = "1", features = ["derive"] }

The CLI ships with the crate behind the cli feature:

cargo install ruststream --features cli

Write a service

use ruststream::codec::JsonCodec;
use ruststream::memory::MemoryBroker;
use ruststream::runtime::{AppInfo, HandlerResult, RustStream};
use ruststream::subscriber;
use serde::Deserialize;

#[derive(Debug, Deserialize)]
struct Order {
    id: u64,
}

#[subscriber("orders")]
async fn handle(order: &Order) -> HandlerResult {
    println!("got order {}", order.id);
    HandlerResult::Ack
}

#[ruststream::app]
fn app() -> RustStream {
    RustStream::new(AppInfo::new("orders", "0.1.0"))
        .with_broker(MemoryBroker::new(), |b| b.include(handle, JsonCodec))
}

#[ruststream::app] generates main, so there is no runtime boilerplate.

Run it

ruststream run                 # start the service (or: cargo run -- run)
ruststream asyncapi gen        # print the AsyncAPI document
ruststream new my-service      # scaffold a new project

Test it

Unit-test handlers against the in-memory broker, with no external service. It does core routing only, so you assert on handler behaviour, middleware, and decoding exactly as in production. See the testing guide.

Documentation

Ecosystem

Concrete brokers live in their own crates and pull ruststream from crates.io.

Contributing

just check    # fmt, clippy, and feature checks
just test     # the test suite

License

Licensed under the Apache-2.0 license.

Inspired by FastStream.