Appearance
Order, duplicates and snapshots
These rules come from SOM's conformance rules for consumers and from how any at-least-once bus behaves. They hold however you receive messages: over the HTTPS pull API or from the queue with AWS credentials.
What the bus guarantees
- Every message is valid. Consumers never see a message the gateway refused.
- Order per
correlation_id, in the order the bus published them. None across differentcorrelation_ids. - At least once. The same
message_idcan arrive again after your own failure, a replay or a redrive. - The producer's message, unchanged. A reader of the queue with AWS credentials gets its exact bytes; the pull API returns the same envelope, parsed, as JSON.
What your consumer must do
| Rule | Why | Test |
|---|---|---|
Choose the payload schema by message_type only | Never by topic, producer or the payload's shape | – |
Ignore message_types you don't recognise, without failing | SOM 1.x can add families, and some types have no 1.0 schema yet | T4 |
Ignore extensions you don't recognise | Vendors add their own, namespaced com.<vendor>. | T4 |
Never branch on som_version | A 1.1.0 message with the same content means the same thing | T5 |
| Tolerate unknown payload fields and enum values from 1.x producers | SOM's compatibility policy lets 1.x producers add them | T5 |
Be idempotent on message_id | Redelivery, replay and redrive send messages again | T2 |
Keep the highest sequence_number per story; drop older snapshots | A redriven or replayed snapshot can arrive after a newer one | T3 |
| Apply a snapshot as a whole replacement, not a merge | A snapshot is the whole story. What's missing from it is gone | T1 |
Leave KILLED, SPIKED, ARCHIVED and ORPHAN stories out of live views | They aren't live stories | T1 |
The tests are on Test your consumer.
Why the highest snapshot wins
The bus refuses a snapshot whose sequence_number doesn't increase, so on the way in, snapshots only move forward. On the way out, a message you failed and had redriven from your dead-letter queue lands behind newer messages of its story, and a replay delivers messages you've already applied. Your consumer is the last line: compare sequence_number with the one you hold for that story_id, and drop anything lower or equal.
How the bus treats newer producers
The bus is strict on the envelope and generous on the payload: a message from a newer 1.x producer may carry payload fields and enum values 1.0 doesn't know, and is delivered to you as sent. See Forward compatibility.