Case study
Event-driven microservices starter kit
Personal project — an end-to-end event-driven architecture, from Rust to Angular
- Rust
- Kafka
- Quarkus
- Java
- PostgreSQL
- Spring Boot
A complete event-driven chain: emission simulators in Rust, Kafka, Quarkus processing services, PostgreSQL, a Spring Boot API / BFF gateway and an Angular front end, with observability across the chain. A personal learning and architecture project, with an open repository.
01
Context and challenge
A personal learning and architecture project: rebuilding an event-processing chain end to end, from the emission simulators through to the supervision front end.
The goal is not a finished product but a deliberate testing ground — exercising an architecture decoupled by events, with observability across the whole chain. The repository is open.
02
My role and scope
Architecture design: service boundaries, Kafka topic definitions and the event contract.
Building the emission simulators in Rust and the processing services in Quarkus (Java).
Setting up the Spring Boot API / BFF gateway and the Angular supervision front end.
03
Technical challenges
Defining a contract that holds
An event stream forces you to decide what identifies an event, how it is ordered, and how a service can reprocess it without producing duplicates. That contract settles quickly: changing it later is paid for by every consumer.
Finding the right service granularity
Splitting too finely multiplies the event contracts to maintain; splitting too coarsely cancels the benefit of decoupling. The right granularity follows the business, not the technology.
Making the chain observable
On an asynchronous chain, latency or failure is rarely visible where it happens: without end-to-end tracking of an event, a distributed system mostly becomes harder to diagnose.
04
Solution and architecture
05
Detailed stack and why
- Rust
- Why this choice — Emission simulators: a self-contained binary with predictable memory use and solid behaviour under sustained throughput — a credible producer to feed the chain.
- Kafka
- Why this choice — A distributed log: events are retained and replayable, and producers and consumers are decoupled through topics rather than direct calls.
- Quarkus
- Why this choice — Java processing services with fast startup and a small footprint, designed for containerised consumers that scale up and down often.
- PostgreSQL
- Why this choice — Projecting business state into a relational model: constraints and transactions exactly where an asynchronous flow needs them most.
- Spring Boot
- Why this choice — The API / BFF gateway: a single entry point for the front end and read aggregation, keeping the processing services out of the user request path.
- Angular
- Why this choice — The supervision front end: structure through modules and services, forms and tracking tables to observe what is flowing through the chain.
06
Results
- Bricks in the chain
- 6Emission, messaging, processing, persistence, exposure, interface
07
What I take away from it
An event-driven chain is designed backwards: the event contracts determine the service boundaries, not the other way round. It is also the project that made the real cost of decoupling tangible — observability is not an add-on, it is what keeps the architecture workable when something gets lost between two services.