🦀 CrabbyQ
CrabbyQ is a declarative, asynchronous Rust framework for building message-driven microservices.
Inspired by the ergonomics of Axum and the messaging mindset of FastStream, CrabbyQ aims to make broker-driven services feel modular, typed, and easy to compose.
Overview
CrabbyQ abstracts away broker subscription loops and route dispatching so you can focus on handlers and domain logic. Internally it is built around Tower, so routes are modeled as tower::Services and the framework can grow naturally toward layers and middleware.
By default, CrabbyQ keeps the core lightweight and enables only the json
format feature. Broker backends such as NATS, Redis, and MQTT are enabled
explicitly through Cargo features.
Current Features
- A broker-agnostic core
Routerwith typed shared state throughset_state(...). - Route registration through
route(...),routes(...),include(...), androute_service(...). towermiddleware support throughlayer(...).- Axum-like extractors such as
State<T>,Subject,Headers,Body, and optional payload extractors likeJson<T>andCbor<T>. - Framework-managed publishing through the
Publishextractor and the corePublisher. - Broker-specific publishers for NATS, Redis, and MQTT.
- RPC-style request-reply through handler return values and
Publisher::request(...). - Graceful shutdown hooks and always-on error logging with optional router-scoped and service-level error topics.
- Multi-argument handler support with the axum-style rule that body-consuming extractors go last.
- Working broker backends for NATS, Redis pub/sub, and MQTT.
NatsRouterandNatsPublisherfor NATS-specific features, including JetStream routes and JetStream publishing.
Features
jsonEnabled by default. AddsJson<T>extractor/response support.cborEnablesCbor<T>extractor/response support.natsEnablesNatsBroker,NatsRouter,NatsPublisher, and JetStream integration.redisEnablesRedisBrokerandRedisPublisher.mqttEnablesMqttBrokerandMqttPublisher.fullConvenience feature for local development and IDE indexing. Enablesjson,cbor,nats,redis, andmqtt.
Quick Start
Stateless Handler
use *;
use NatsBroker;
use info;
async
async
For the NATS examples above, enable the nats feature:
= { = "0.1.0", = ["nats"] }
State and Extractors
use *;
use Deserialize;
;
async
Body-consuming extractors such as Body, Json<T>, and Cbor<T> should be the last handler argument.
RPC Through Return Values
use *;
use ;
async
Examples
The repository includes runnable examples for stateless handlers, state,
extractors, publishers, RPC, multi-router composition, and graceful shutdown.
See examples/README.md for the full list of runnable examples and example commands.
Architecture Notes
- Route keys are broker-facing identifiers, not HTTP paths.
include(...)composes routers without rewriting route keys.- Duplicate route keys panic during router construction instead of failing later at runtime.
- Extractors are split into:
FromEventParts<S>for metadata-like values.FromEvent<S>for full-event or payload-consuming values.
- Publishers are injected by the framework at
into_service(...)time, so handlers can publish without manually wiring broker clients through state. Publisherstays broker-agnostic and is the injected handler capability. Broker-specific publishing features live in broker-specific publishers such asNatsPublisher,RedisPublisher, andMqttPublisher.- RPC replies are sent automatically when the incoming message carries
reply_tometadata and the handler returns a response value. - Middleware is exposed through
Router::layer(...)and currently composes routes through boxedtower::Services for implementation simplicity. A more zero-cost internal pipeline is planned as the framework matures. - Broker-specific features live in broker-specific routers and publishers. For
example,
NatsRouterandNatsPublisherextend the core API with JetStream-specific routing and publishing. - Broker backends and message formats are feature-gated so embedded and other constrained targets can keep the dependency footprint smaller.
- CrabbyQ focuses on routing and service ergonomics. For NATS JetStream
storage APIs such as Key-Value and Object Store,
async-natsalready provides a solid API, so CrabbyQ does not add extra wrapper layers there.
Roadmap
Future development focuses on:
- A more zero-cost internal middleware pipeline on top of the current
tower::Layerintegration. - Broker-specific extractors for transport metadata such as NATS and JetStream delivery context.
- Better typed rejection and error response handling.
- More broker backends such as RabbitMQ and Kafka.
- Additional payload formats such as Protobuf and MsgPack.
Contributing
If you are interested in building "Axum for message brokers" in Rust, contributions are welcome through:
- Feature requests and API design discussions.
- Pull requests for new broker implementations.
- Documentation improvements.