Skip to main content

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:

  1. Orchestration (API calls): Services directly call Book-Keeper's REST API to record transactions
  2. 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)

  1. 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
  2. Book-Keeper Subscription: Dedicated internal event handlers listen for these external events

  3. Event Translation: Handlers translate business events into RecordJournalEntryCommand and dispatch internally

  4. 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_id
  • net_pay
  • gross_pay
  • tax_withheld
  • deductions

NOT:

  • Pre-calculated debit/credit entries
  • Account codes
  • Journal entry formatting