Course outline

NestJS / Advanced: lifetime and distributed-work evidence / Lesson 14

Message transports, contracts and error semantics

Adapt shared use cases to message delivery without importing HTTP assumptions about identity, acknowledgment or retries.

About 4 min readContent reviewed
On this page

Lesson goals

  • Distinguish request-response messaging from event delivery.
  • Define schema version, scope and failure policy for each transport.

A message pattern does not define delivery guarantees

Nest microservice adapters expose request-response and event-oriented programming models, but the broker or transport determines routing, acknowledgment, redelivery and durability. A MessagePattern label is not a transaction or an exactly-once guarantee. Choose one documented transport and pin its packages before writing operational configuration. Keep the domain use case independent of transport payload wrappers. A consumer can reuse publication policy, but must establish trustworthy caller or service context rather than accepting a tenant field as permission. Different trust boundaries require explicit adapters even when they call the same service method.

Version the payload and name the logical operation

The JSON is a synthetic event contract, not a broker command or an observed delivery. Event identity supports replay recognition, aggregate revision supports ordering under its own policy, and schemaVersion names the payload contract. They are distinct fields with distinct meanings. Validate size, shape and permitted domain values before source effects, and verify the authenticated producer scope through the chosen transport’s trust model. Avoid carrying credentials or an entire HTTP request in message data. A trace identifier can correlate work but does not itself authenticate who sent it.

json Synthetic versioned event
{"schemaVersion":1,"eventId":"evt-17","type":"course.published","tenantId":"lab-a","courseId":"c1","revision":5,"traceId":"synthetic-trace"}

No message is published. The record separates payload version, event identity, object identity and object revision.

Separate delivery acknowledgment from business completion

An adapter receiving bytes does not prove the domain effect committed. Acknowledging before durable work can lose the action after a crash, while acknowledging afterward can cause redelivery if the acknowledgment is lost. Use the transport’s documented mechanism and make effects replay-safe. HTTP exceptions and status codes do not automatically become meaningful RPC or broker failures; choose the appropriate exception/error contract. In a hybrid app, configure global pipes, guards and filters deliberately for each context instead of assuming the HTTP pipeline is inherited everywhere. Test these mappings with synthetic messages in an authorized environment.

Reject stale state without pretending delivery is complete

The local reducer applies only newer revisions to a synthetic view. Duplicate revision five and a late revision four cannot overwrite revision six. It does not guarantee that all intermediate events arrived or that separate events with the same revision are identical. A real consumer may need event-ID deduplication and gap recovery through an authoritative source. The model tests an ordering policy only, without a broker, subscription, database or acknowledgment. Keep per-aggregate ordering and multi-aggregate workflows separate; one scalar revision cannot define a universal total order across every business object.

javascript Complete offline revision-order model
let revision=3;
for (const incoming of [5,5,6,4]) revision=Math.max(revision,incoming);
console.assert(revision === 6);

The final view revision is six. This does not verify complete event history or any transport delivery guarantee.

Bound retries, payloads and consumer work

Set domain-aware attempt limits, backoff and failure retention rather than retrying malformed payloads forever. Bound message size and concurrent source work, preserve cancellation/deadline assumptions and keep private values out of logs. A poison message needs a reviewable failure path without blocking all healthy work indefinitely. Document how schema evolution and producer rollback interact with retained events. This course parses the event and runs only the revision reducer; no broker, service listener, network acknowledgment or transport-specific exception handling was executed. Real verification must target the exact adapter and versions under authorized isolated conditions.

Common errors and fixes

An HTTP error becomes an undefined broker outcome

Why it happens
Transport-specific failure semantics were assumed portable.
How to fix it
Define the selected RPC/event error and acknowledgment contract.
Prevent it next time
Test each supported context separately.

A duplicate message repeats the side effect

Why it happens
Delivery was assumed exactly once.
How to fix it
Use stable event identity and durable replay-safe effects.
Prevent it next time
Test lost acknowledgment after committed work.

An unsupported payload version is silently processed

Why it happens
Schema evolution had no explicit admission rule.
How to fix it
Validate version and route unsupported data to safe failure.
Prevent it next time
Retain old/new producer-consumer fixtures.

Check your understanding

1. Why are schemaVersion and revision not interchangeable?

Show worked solution

The schema version identifies how to interpret the payload, while revision orders a particular object’s state under its domain contract. An old-format event can carry a new object revision. Validate both meanings independently and do not infer payload compatibility from a larger aggregate revision.

2. Does the reducer prove no publication event was lost?

Show worked solution

No. It sees only supplied revision numbers and retains the largest. Missing intermediate events remain undetected unless the application defines gap semantics and recovery. Use event identity and authoritative reconciliation as required, then separately verify transport retention and acknowledgment with the real adapter.

Key takeaways

  • Message patterns do not replace transport and domain delivery contracts.
  • Version, identity, revision and acknowledgment establish different facts.

Official references