Anatomy of a Message
In Axon, all communication between components is done with explicit messages, represented by the
Messageconsists of a Payload, which is an application-specific object that represents the actual functional message, and Meta Data, which is a key-value pair describing the context of the message.
Message's sub-interfaces represent a specific type of message, and defines additional information that describes that Message. Unlike Meta Data, this additional information defines information required for correct processing of that type of message.
Messages are immutable. That means that, to add a Meta Data element, you effectively create a new Message instance, with an additional (or other) Meta Data element. To still be able to consider two Java-instances of a message as representing the same conceptual Message, each message has an identifier. Changing the Meta Data of a message will not change this identifier.
Meta Data of messages typically describe the context in which a Message was generated. For example, Meta Data might contain information about the message that caused this Message to be generated (e.g. Command handlers generate Events based on an incoming Command).
In Axon, Meta Data is represented as a Map of String to Object. While you are free to add any type of object as the Meta Data value, we strongly recommend sticking to primitives and Strings (or at most simple objects). Meta Data does not come with the same flexibility as the payload when it comes to structural changes.
Unlike a regular
MetaDatain Axon is immutable. Mutating methods will create and return a new instance, instead of modifying an existing one.
MetaData metaData = MetaData.with("myKey", 42) // 1
.and("otherKey", "some value"); // 2
- 1.Creates a
MetaDatainstance with the indicated key-value pair
- 2.Add an additional key-value pair, returning a new instance of
Meta Data in a message works similarly:
EventMessage eventMessage =
GenericEventMessage.asEventMessage("myPayload") // 1
.withMetaData(singletonMap("myKey", 42)) // 2
.andMetaData(singletonMap("otherKey", "some value")); // 2
- 1.Create an EventMessage with "myPayload" as the payload
withMetaDatareplaces any Meta Data in the message with the given Map.In this case
java.util.Collections.singletonMap()is used to define a single entry.
andMetaDataadds the entries from the given Map to the Message's metadata. Existing entries with equal keys are overwritten.Note - about
Map<String, Object>, meaning that instead of passing a
singletonMap(or any other type of Map), you can also use
MetaData.with(key, value). As
MetaDatais immutable, all mutating operations of
Mapwill throw an
Certain types of messages provide extra information (on top of what the Message provides). For example, an
EventMessage(an interface extending
Message) also provides a timestamp, representing the time at which the event was generated. The
QueryMessagecarries, besides Payload and Meta Data, a description of the type of response that the requesting component expects.