0049: Event-Driven Integration Pattern for Book-Keeper
Date: 2025-11-22
Status: Accepted
Service: book-keeper
Context
Other microservices (e.g., invoicing-service, payroll-service, orders-service) need to record financial transactions in the Book-Keeper's general ledger when business events occur.
Two primary integration patterns exist:
- Orchestration (API calls): Services directly call Book-Keeper's REST API to record transactions
- Choreography (Event-driven): Services publish business events; Book-Keeper subscribes and reacts
Key considerations:
- Services should not need to understand accounting principles or how to construct journal entries
- Book-Keeper availability should not block critical business operations
- Integration logic should be maintainable and testable
- Domain boundaries must be respected (no tight coupling between bounded contexts)
Decision
The primary integration pattern will be Event-Driven Choreography. The REST API serves as a secondary interface for administrative use.
Choreography Pattern (Primary)
-
External Event Publishing: Services publish business-significant domain events to the event bus (NATS/Kafka)
- Example:
InvoiceIssued,PaymentReceived,PayrollRunCompleted - Events contain business data, NOT pre-formatted accounting entries
- Example:
-
Book-Keeper Subscription: Dedicated internal event handlers listen for these external events
-
Event Translation: Handlers translate business events into
RecordJournalEntryCommandand dispatch internally -
Accounting Logic Centralized: All logic for creating journal entries remains within Book-Keeper context
API Pattern (Secondary)
The POST /api/book-keeper/v1/journal-entries endpoint remains available for:
- Manual entry UIs
- Administrative tools
- Scenarios requiring immediate ledger feedback
- Not recommended for routine inter-service communication
Consequences
Positive
- Loose Coupling: External services don't need to know accounting principles or Book-Keeper's API schema
- Resilience: If Book-Keeper is unavailable, events queue in NATS and process when service recovers
- Domain Purity: Accounting logic stays centralized; doesn't leak into other bounded contexts
- Auditability: Event bus provides additional audit trail of what triggered each transaction
- Scalability: Can scale Book-Keeper event consumers independently
Negative
- ** Eventual Consistency**: Transactions are not immediately visible in ledger (acceptable for most financial systems)
- Event Schema Management: Must maintain backward compatibility for event schemas
- Debugging Complexity: Harder to trace end-to-end flow compared to synchronous API calls
- Infrastructure Dependency: Requires robust event bus infrastructure (NATS/Kafka)
Neutral
- Dual Patterns: Supporting both patterns requires maintaining two integration paths
- Consumer Group Management: Need to properly configure consumer groups for scaling
Implementation Notes
Services must publish events with sufficient business context. For example, PayrollRunCompleted should include:
employee_idnet_paygross_paytax_withhelddeductions
NOT:
- Pre-calculated debit/credit entries
- Account codes
- Journal entry formatting