Integrations Prototype
Clamp does not write its own web server or database driver. An integration is an optional package over the crate that already does the job: it owns the composition rules and leaves that crate's API in your hands.
Status. These integration packages and examples are prototype source in their repositories; crates.io releases are still gated on license, ownership and API review. HTTP and PostgreSQL are demonstrated with example 06; messaging is demonstrated with example 07. Workers, the outbox/inbox pattern and the scheduler are built and tested — including live runs against PostgreSQL 18.6 and NATS JetStream 2.11 — in examples 08–10. Core and Kernel depend on none of them. Decision records: ADR 0005 and ADR 0006 in rustclamp/docs/adr.
HTTP · rustclamp-http Prototype#
Built on Axum and Tower. Modules contribute routes to an HttpRoutes<Public> target through Kernel's TargetComposition, the same contribution path CLI commands use. Routes are validated and compiled before a listener binds or a pool opens.
| Concern | The package owns | You keep |
|---|---|---|
| Routes | Path validation and compilation, conflict detection | The compiled Axum Router — add ecosystem middleware or mount it in an existing server |
| Requests | Context: tenant, correlation, cancellation, bounded deadline | Authorization, enforced inside your domain operation |
| Responses | Decoding, content negotiation, typed error disclosure, request limits | The semantic result; JSON, HTML, XML, binary and event-stream all derive from it |
| Serving | Bounded streaming, disconnect cancellation, graceful drain of a listener you own | The TcpListener and when to shut it down |
// Routes are validated and compiled before binding the process-owned listener.
let router = application_router(users)?;
let listener = tokio::net::TcpListener::bind(&address).await?;
rustclamp_http::serve(
listener,
router,
rustclamp_http::ShutdownReceiver(shutdown_rx),
Duration::from_secs(5),
)
.await?;
PostgreSQL · rustclamp-postgres Prototype#
Built on SQLx. SQL and transactions stay in your adapters; there is no ORM.
- Qualified pools. Typed identities such as
PrimaryandAnalytics. Clones of one pool are shared within an application; separately constructed pools stay independent. This is process-local — no cross-process sharing is claimed. - Ownership. A managed pool is closed by the process; an external one is left to its owner, as on Lifecycle.
- Health probes and explicit migrations. Migrations are planned and run on purpose. None runs when a pool connects — automatic schema changes at startup are unsafe once more than one process deploys.
- Transactions per execution. In example 06 an infrastructure repository created for one execution holds the transaction; the domain only sees its
UserRepositoryport.
Integration tests against PostgreSQL 18.6 cover migration apply and rollback, health, transaction rollback, Users commit and rollback, concurrent tenant isolation, and pool shutdown and reconnection. They are ignored by default and run explicitly:
RUSTCLAMP_TEST_DATABASE_URL=postgres://... cargo test --offline --locked --manifest-path postgres/Cargo.toml --test postgres -- --ignored
Messaging · rustclamp-messaging Prototype#
Work that crosses a process boundary needs a stable contract; in-process events are just Rust values. MessageEnvelope carries a stable message identity, a semantic name, a schema version, a correlation identity, an optional causation identity, an optional deadline and a JSON payload. Applications map their typed events to it explicitly.
MessageBus is a typed Core capability. A bounded in-memory bus serves tests and development; NATS JetStream is the real transport, with durable pull consumers, explicit acknowledgements and bounded batches. Delivery is at least once, so handlers are written to be duplicate-safe.
Workers · rustclamp-worker Prototype#
Modules contribute handlers by message name and schema version; the worker target rejects invalid or duplicate declarations before any message is fetched. Handlers classify failures:
| Outcome | What happens |
|---|---|
| Success | Acknowledged |
| Retryable | Retried with bounded backoff, five attempts in total |
| Permanent | Dead-lettered, not retried |
| Unknown | Preserved in the dead-letter record and never retried automatically — including a timeout at the message deadline |
A worker stops fetching on Ctrl-C and finishes or times out its current delivery. A delivery lost with its process is redelivered after the lease.
Outbox and inbox Prototype#
In example 09 an order, its inventory change and its outbox message commit in one PostgreSQL transaction; a separate publisher sends pending rows to JetStream and marks them only after broker confirmation. A durable inbox deduplicates redelivery. The evidence includes stopping the publisher, stopping the broker, and killing a worker before its transaction committed — orders were published once the pieces came back, and none was processed twice.
Scheduler · rustclamp-scheduler Prototype#
Jobs are contributed like routes and driven by Core's Clock, so tests advance time through regular and missed intervals instead of waiting. On shutdown the scheduler stops admitting new runs before active jobs drain. No cron daemon, no async runtime required.
What they cost#
The console-only build of example 06 resolves 8 packages and excludes Axum, SQLx and Tokio. Selecting HTTP brings it to 62, PostgreSQL to 160. A request through the Clamp HTTP path took 1.84× the direct Axum route (6,857 vs 3,728 ns), paying for contributed routing, middleware and negotiation; a PostgreSQL read through the Users adapter was within noise of direct SQLx. Full tables on Evidence.