The Library Inventory System
Every module from here on either builds a piece of this system or hardens a piece you already built. Get the shape of it into your head now, and every later "why are we doing this" question answers itself.
Learning objectives
- Beginner: Describe the Library Inventory System's producer/consumer split in one sentence.
- Intermediate: Explain why the system uses two separate microservices instead of one, tied to Kafka as the connecting layer.
- Advanced: Anticipate which later module hardens which specific piece of this architecture, before being told.
The reference system is a small library's inventory tracker, built as two independently deployable Spring Boot microservices that never call each other directly — they only communicate through Kafka:
- library-events-producer — a REST API. A client (or another system) sends a LibraryEvent (adding or updating a Book) via HTTP. The service validates it and publishes it as a Kafka record. It never touches a database directly.
- library-events-consumer — has no public write API for library events. It subscribes to the Kafka topic, processes each event (insert for NEW, update for UPDATE), and persists the result to PostgreSQL. It separately exposes read/CRUD REST endpoints over the data it owns.
End-to-end flow: REST client → producer service → Kafka topic → consumer service → PostgreSQL. The two services share zero direct coupling — the topic is the entire contract between them. __ client__ Spring Boot service__ Kafka topic__ database
Domain model (used consistently across every code sample on this site)
| Type | Fields | Notes |
|---|---|---|
| LibraryEvent | libraryEventId, libraryEventType (enum: NEW / UPDATE), book | The record published to and consumed from Kafka. |
| Book | bookId, bookName, bookAuthor | Embedded in LibraryEvent; also has its own CRUD endpoints on the consumer (Module 12). |
◆ Under the hood — why the producer doesn't touch the DB
This isn't an arbitrary constraint — it's the point of the architecture. The producer's only job is "accept a request, validate it, and durably record that it happened" (via Kafka's own durability, not a database write). This keeps the producer's write path fast and free of a database round-trip, and means any number of future consumers (a search index, an analytics pipeline, a notification service) can independently subscribe to library-events later without the producer ever knowing they exist or being modified to support them.
✓ Quick recap
How do the producer and consumer services communicate? Only through the library-events Kafka topic — never a direct API call between them. Which service owns the PostgreSQL database? The consumer — the producer has no database dependency at all. What distinguishes a NEW vs. UPDATE LibraryEvent? The libraryEventType enum, which the consumer's service layer uses to decide insert vs. update logic.
Want a visual for this concept?
Generate a diagram tailored to “The Library Inventory System” — the AI picks whichever visual (flowchart, comparison, sequence, etc.) best fits.
Sign in to generate a visual →