Work Event-driven Java service

An event-driven Java service that stays correct when messages arrive twice

Our reference implementation of one service in an event-driven compliance platform: a framework-free domain model, a transactional outbox and idempotent Kafka consumers, tested against real MySQL and Kafka instead of mocks.

Sector
Backend engineering · Our product
Our part
Architecture and decision records, Domain model, Messaging, Testing
Built with
Java 21, Spring Boot 3.4, MySQL, Kafka, Flyway, Testcontainers, GitHub Actions
Service
Custom software development →
Concept illustration · Fictional identity and sample interface, not the original product.

The starting point

When services talk only through events, two things break quietly: a change and its event committing separately, so the platform drifts; and a consumer doing the work twice when a message is redelivered. This service shows both solved properly.

What we were responsible for

We designed and built the service, its tests and the architecture records.

What we built

  • The lifecycle is a state machine

    Allowed transitions live in one place in the model, and the API has no way to set a status directly.

  • Transactional outbox

    Domain events are saved in the same transaction as the change and published to Kafka afterwards — proven by an integration test against a real database.

  • Idempotent consumers

    Incoming events are applied once even when Kafka redelivers them, with backoff and a dead-letter topic.

  • Layering enforced by the build

    Architecture tests fail the build if the domain imports a framework, a transaction appears outside the application layer, or code reads the clock directly.

  • Decisions written down

    Decision records for the outbox, idempotent consumers and the framework-free domain.

Where it stands

The full suite, including integration tests on real MySQL and Kafka containers, runs on GitHub Actions on every push.

Working on something similar?

Book a 30-minute call or send a brief. If the scope is clear, you get a written fixed quote within one or two business days.