About event-driven-messaging
Event-Driven Messaging is a playbook for developers designing event-based systems. It covers event contracts, durable publication, idempotent consumers, bounded retries, and integration testing.
Key features
- 01Define versioned immutable event envelopes
- 02Publish after durable state changes
- 03Use an outbox for coordinated database and broker writes
- 04Make consumers idempotent
- 05Bound retries and route poison messages
- 06Test compatibility and delivery edge cases
Use cases
- 01Design event schemas for evolving services
- 02Prevent duplicate processing in consumers
- 03Handle transient and permanent message failures
- 04Test reordered, delayed, or poison messages
Install
Copy the command and run it in a terminal.
$
npx skills add https:/ / github.com/ rrezartprebreza/ spring-boot-skills --skill event-driven-messagingAfter installing, type/event-driven-messagingin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
agents/openai.yamlexamples/bad-consumer.javagood-consumer.javaDetails
From the project READMEEvent-Driven Messaging
Design for at-least-once delivery unless the complete system proves stronger semantics.
Event contract
- Use an immutable event envelope with
eventId,eventType,occurredAt,schemaVersion, and payload. - Treat published schemas as APIs. Add fields compatibly and never silently change meaning.
- Put correlation and causation IDs in headers or the envelope.
- Do not publish JPA entities or framework-specific serialization shapes.
Producer rules
- Publish only after the originating state change is durable.
- Use a transactional outbox when database state and broker publication must agree.
- Use deterministic partition keys when per-aggregate ordering matters.
- Configure delivery timeout and acknowledgements explicitly.
Consumer rules
- Make handlers idempotent with a durable processed-event record or naturally idempotent write.
- Keep the transaction boundary around the state change and idempotency marker.
- Classify transient and permanent failures before configuring retries.
- Bound retries with backoff, then route poison messages to a dead-letter destination.
- Preserve the original event, failure reason, and attempt count for replay.
Testing
- Test serialization compatibility and handler idempotency.
- Use Testcontainers for broker integration tests.
- Test duplicate, reordered, delayed, and poison messages.
Examples
- See
examples/good-consumer.javaandexamples/bad-consumer.java.
Gotchas
- Agent assumes exactly-once delivery because the broker supports transactions - end-to-end side effects still need idempotency.
- Agent retries validation failures forever - dead-letter permanent failures promptly.
- Agent publishes inside a database transaction without an outbox - a crash can split state and event delivery.
- Agent uses a random partition key - ordering for one aggregate is then lost.
- Agent deserializes directly into a JPA entity - use a versioned event contract.
Comments
Markdown supported