ediverse Explore the platform

Spotlight PEPPOL BIS Billing 3.0 The EU e-invoicing mandate is here — France Sept 2026, Belgium Jan 2026, Germany 2025.

Domain Event

The business fact frozen in time becoming the temporal boundary between bounded contexts — foundation of any serious event-driven architecture.

Problem

An EDI hub receives an INVOIC from a partner. Three independent teams need it: finance to book it, logistics to release payment, audit to archive 10 years with signature. If the reception service calls all three directly (synchronous HTTP), it knows their existence and API. A new team (machine learning, tax compliance) must be wired in explicitly each time. Worse: if finance is down, reception blocks. We have re-created a distributed monolith over HTTP.

Forces

  • The consequences of a business fact are many. An invoice received triggers accounting, payment, archive, KPIs, fraud detection.
  • The producer must not know the consumers. Otherwise, adding a consumer means modifying the producer.
  • Consumers have different cadences. Accounting = real-time; KPIs = daily batch; ML = quarterly.
  • Business history is valuable. An invoice received on May 12 at 14:32 remains true even if the system is replayed 6 months later.

Solution

Model the business fact as an immutable Domain Event named in the past tense: InvoiceReceived, OrderApproved, ShipmentDispatched. The producer emits the event on a bus (Kafka, AWS EventBridge, NATS), with a unique id, a signed timestamp, and a payload carrying the data needed for autonomous consumption. Consumers subscribe. Adding a consumer has no impact on the producer. Events are persisted — replayable — and can ground Event Sourcing.

{
  "type": "InvoiceReceived",
  "eventId": "01H...ULID",
  "occurredAt": "2026-05-16T08:30:12.345Z",
  "aggregateId": "invoice-INV-2026-0001234",
  "aggregateVersion": 1,
  "payload": {
    "invoiceNumber": "INV-2026-0001234",
    "supplierId": "GLN-3010234567890",
    "buyerId": "GLN-3060987654321",
    "amount": { "value": 12500.00, "currency": "EUR" },
    "issueDate": "2026-05-15",
    "dueDate": "2026-06-14"
  },
  "metadata": {
    "source": "edi.parser.edifact",
    "traceId": "00-abc...-01"
  }
}

EDI implementation

Concrete case: the EDIFACT parser receives an INVOIC, validates syntax/semantics, and publishes InvoiceReceived on Kafka edi.events.v1. Three independent consumers: (1) accounting service creates a journal entry, (2) archive service XAdES-signs and stores in S3 Object Lock for 10 years, (3) notification service emails the client. If tomorrow we add a fraud ML detection service, we create a new consumer: the parser is untouched. Events are versioned (InvoiceReceived.v1, InvoiceReceived.v2) to handle schema evolution. The Outbox pattern publishes the event atomically with the DB commit. Apache Camel, Spring Modulith, Axon Framework tool this pattern in Java; EventCatalog documents the schemas.

Anti-patterns

  • Events named in the present. SendInvoice or CreateInvoice are commands, not events. Confusing the two creates disguised coupling.
  • Events too fine (CRUD events). InvoiceFieldUpdated for each field: noise, loss of business meaning. Emit InvoiceCorrected with the new business snapshot.
  • Events too rich. If the payload carries every possible state, we return to a shared library. The consumer must be able to use it and ask for extras through APIs if needed (Content Enricher).
  • Events tied to infrastructure. KafkaMessageReceived or JmsMessageDelivered are not business events. They may be useful technically but do not carry domain meaning.

Sources

  • Evans E.Domain-Driven Design, Addison-Wesley 2003. Founding concept; expanded in later editions and by the DDD community.
  • Fowler M.Domain Event (martinfowler.com, 2005). The pedagogical definition. martinfowler.com — DomainEvent
  • Vernon V.Implementing Domain-Driven Design, Addison-Wesley 2013. Chap. 8 "Domain Events" with Java examples.
  • Microsoft Architecture Center — Domain events: design and implementation. The pattern transposed to .NET. learn.microsoft.com — Domain events
  • CloudEvents spec. The CNCF standard for cross-system event serialisation. cloudevents.io