Quick start
The fastest way to a running service is to scaffold one with cargo generate.
Scaffold a project
cargo install cargo-generate
cargo generate --git https://github.com/powersemmi/ruststream templates/memory --name my-service
cd my-service
Scaffolding needs only cargo generate. templates/memory is the starter template for the
in-memory broker. A broker crate that ships a template is scaffolded the same way, naming that
crate's repository and the template's path (for example
--git https://github.com/powersemmi/ruststream-nats templates/nats); the broker's own
documentation names the templates it has. cargo generate writes an idiomatic, multi-file project:
my-service/
├── Cargo.toml
└── src/
├── main.rs # #[ruststream::app] builds the service and mounts the router
├── orders.rs # handlers as #[subscriber] functions (one publishes a reply)
└── routes.rs # collects the handlers into a Router
Run it
#[ruststream::app] generates main, so the binary already understands the framework commands:
cargo run -- run # or: ruststream run, with the CLI installed
cargo run -- run starts a tokio runtime. The service runs until you press Ctrl+C. It needs
no external broker. The template turns on the logging feature, so the service prints its log
to the terminal, and the handlers log through tracing.
Generate the AsyncAPI document
cargo run -- asyncapi gen
The command prints the AsyncAPI document as JSON. The output flags (-o, --yaml) and the
document itself are covered in the asyncapi module.
What the entry point looks like
- Macros
- Manual
mod orders;
mod routes;
use ruststream::memory::MemoryBroker;
use ruststream::runtime::{AppInfo, RustStream};
#[ruststream::app]
fn app() -> RustStream {
RustStream::new(AppInfo::new("orders-service", "0.1.0")).with_broker(MemoryBroker::new(), |b| {
let router = routes::orders();
b.include_router(router);
})
}
mod orders;
mod routes;
use std::process::ExitCode;
use ruststream::memory::prelude::*;
use ruststream::runtime::cli::run_main;
fn app() -> RustStream {
RustStream::new(AppInfo::new("orders-service", "0.1.0")).with_broker(MemoryBroker::new(), |b| {
let router = routes::orders();
b.include_router(router);
})
}
// What `#[ruststream::app]` writes around the builder: the `run` and `asyncapi gen` commands.
fn main() -> ExitCode {
run_main(app)
}
You write a function that builds the service; #[ruststream::app] turns it into main.
Next
- Understand each piece in the tutorial.
- Learn the handler forms in Subscribers.
- Drive everything from the CLI.