Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Microservice Operations, Testing, and Interoperability

Reliability

Broker delivery is at least once after consumer failure. Make command writes and event effects idempotent. Store MessageContext::event_id() with the business transaction and reject an already-committed ID. For commands, use a business idempotency key in the payload because correlation IDs identify attempts, not business operations.

Concurrency is bounded per subscription by max_handler_concurrency; also size database pools and downstream limits. Respect the propagated deadline and cancellation_token() in long-running work. Shutdown stops intake, waits for tasks, then runs normal provider/module hooks.

Remote failures are sanitized. Log internal exception sources on the service; return stable public codes and safe details to callers. Monitor broker connectivity, request latency/timeouts, no-responder errors, pending/redelivered events, delivery attempts, dead-letter destinations, handler saturation, and shutdown timeouts.

Tests

Handler metadata and invocation can be tested without a broker:

#![allow(unused)]
fn main() {
let container = caelix::build_container::<AppModule>().await?;
let handler = OrdersMessages::definition()
    .handlers()
    .into_iter()
    .find(|handler| handler.pattern == "orders.create")
    .unwrap();
let result = handler.invoke(&container, context, serde_json::json!({"id": 1})).await?;
}

Use broker-backed integration tests for envelopes, queue/consumer competition, deadlines, reconnection, retry, dead letters, and shutdown. Run isolated NATS with JetStream or Redis 6.2+, use unique stream/subject prefixes, start MicroserviceRuntime, create a real MicroserviceClient, and always call shutdown(). The repository integration tests and event probes cover the supported transports.

NestJS interoperability

Maintained executable examples live in examples/nestjs-nats-interoperability and examples/nestjs-redis-interoperability. They are the authoritative cross-framework demonstrations.

Caelix uses its own versioned JSON envelope for correlation IDs, deadlines, headers, typed payloads, safe failures, and event IDs. NestJS’s stock transport serializer is therefore not wire-compatible by itself; the examples install the matching custom envelope adapter. Keep that adapter aligned whenever the protocol version changes.