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
sourceidentifying the system or service, which published the event, e.g.tag://service:spring:library - a
subjectidentifying the domain entity that the event belongs to, e.g./books/ab9c7d71-9a5e-4664-8b75-73f4d04cac5e - a
typerepresenting the event type, e.g.com.example.book.purchased.v1 - the actual event
datarepresented 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
specVersionidentifying the version of the Cloud Events Specification - an
idwhich uniquely identifies the event within the global event stream of the event store, e.g. an auto-incremented number - the
timethe event was written to the event store - a
dataContentType, which is alwaysapplication/json - a
hashandpredecessorHashrepresenting 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
payloadrepresenting the actual Java event object, e.g.BookPurchasedEvent - the
metaDatacontaining 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.