Event Representations
Events published or consumed using OpenCQRS are stored within the EventSourcingDB, which in turn uses the Cloud Events Specification as a basis for representing events in JSON.
The following diagram depicts how these events are represented within the esdb-client
and framework
modules and an exemplary application domain
:
classDiagram
direction RL
namespace domain {
class Map~String, ?~
class BookPurchasedEvent {
<<record>>
+String isbn
}
}
namespace framework {
class EventData~E~ {
<<record>>
+Map~String, ?~ metaData
+E payload
}
}
namespace esdb-client {
class EventCandidate {
<<record>>
+String source
+String subject
+String type
+Map~String, ?~ data
}
class Event {
<<record>>
+String source
+String subject
+String type
+Map~String, ?~ data
+String specVersion
+String id
+Instant time
+String dataContentType
+String hash
+String predecessorHash
}
class Client {
<<interface>>
+write(List~EventCandidate~)
+read() List~Event~
}
}
BookPurchasedEvent <--> EventData: represented by 'payload'
Map~String, ?~ <--> EventData: represented by 'metaData'
EventData~E~ --> EventCandidate : serialized into 'data'
EventData~E~ <-- Event : deserialized from 'data'
EventCandidate --> Client: write
Event <-- Client: read
The diagram includes both the write and read representations for the BookPurchasedEvent
domain event.
Events and EventCandidates
Within the esdb-client
module events are distinguished with respect to whether they were read from (Event
)
or intended to be written (EventCandidate
) to the event store.
Both share a common set of attributes:
- a
source
identifying the system or service, which published the event, e.g.tag://service:spring:library
- a
subject
identifying the domain entity that the event belongs to, e.g./books/ab9c7d71-9a5e-4664-8b75-73f4d04cac5e
- a
type
representing the event type, e.g.com.example.book.purchased.v1
- the actual event
data
represented as generic map, e.g. any valid JSON content
Deviations from Cloud Events Specification
Both EventCandidate
and Event
are in-memory representations of the JSON read from or written to the event store.
They do not strictly adhere to the structure and naming of attributes defined within the
Cloud Events Specification or the EventSourcingDB API.
An EventCandidate
represents an intent for publishing a new event to the event store and thus is limited to the
aforementioned common set of attributes. An Event
, read from the event store, is an enriched representation
additionally containing:
- a
specVersion
identifying the version of the Cloud Events Specification - an
id
which uniquely identifies the event within the global event stream of the event store, e.g. an auto-incremented number - the
time
the event was written to the event store - a
dataContentType
, which is alwaysapplication/json
- a
hash
andpredecessorHash
representing the hashes of the current event and its predecessor
Event Payload and Metadata
Within the framework
the data
attribute of EventCandidate
and Event
,
respectively, is transformed into an EventData
representation with:
- the
payload
representing the actual Java event object, e.g.BookPurchasedEvent
- the
metaData
containing additional meta-data accompanying the event
Info
The Cloud Events Specification is constrained to having only a single
data
attribute per event. Hence, the framework
uses EventData
to distinguish between the actual Java object payload and its optional meta-data.
Application Events
The event persistence within the framework
module is focused on writing and reading Java object events, that
can be serialized to and deserialized from JSON. Accordingly, EventData
is used as a wrapper for representing the
object payload and its optional meta-data. The event type
indicates which Java class to use for deserializing
the events. This should be configured using explicit type registration
for production use.