tl;dr
- Eventide allows custom metadata
- Don’t put it directly on the
metadata
property of a message - Put it in the
metadata.properties
hash if you want that metadata propagated to later messages - Put it in the
metdata.local_properties
hash if you don’t want it propagated to later messages
properties
are followed
When using the Eventide Project, you use message’s metadata
property to hold things related to the mechanics of messaging. So things like user_id
or timing information about your domain operation don’t belong in metadata
– they are data
properties.
Also, the attributes directly on metadata
are decided by the framework. So don’t try adding things there.
For custom metadata properties, you assign things to the [metadata.properties](http://metadata.properties)
hash. A common use case for this is a trace_id
. Imagine assigning each incoming HTTP request a unique identifier that you put into whatever command that handler writes as follows:
# Inside some HTTP handler
deposit = Deposit.build
deposit.deposit_id = "123"
deposit.account_id = "abc"
deposit.amount = 5
deposit.metadata.properties["trace_id"] = request.trace_id # xyz-456
Here we imagine the existence of a request
object that contains a trace_id
.
When handling a command, we typically use the follow
method of the resulting message class. Deposit
is typically followed by Deposited
:
# ...earlier code in handler
desposited = Deposited.follow(deposit)
This deposited
event’s metadata will have our trace_id
:
puts deposited.metadata.properties["trace_id"]
# => "xyz-456"
As long as you use follow
, Eventide will propagate your metadata.properties
to the following messages. In the case of our trace_id
, you’d now have a single identifier that originated with your user input attached to every message in your system resulting from that stimulus.
local properties
are not followed
Sometimes you want custom metadata
on a message, but you don’t want it follow
ed. That is the job of the metadata.local_properties
. Again, this is strictly for data related to the mechanics of messaging.
A use case I’ve had for this is I once needed a stream that held onto messages intended for multiple different streams until some other event happened. When we got that other event, we needed to write the “buffered” events to their correct stream.
Using metadata.local_properties
removed the complication. When we wrote the message into the buffer, we assigned the stream name where it ultimately ended up as a target_stream_name
property:
buffered_event.metadata.local_properties["target_stream_name"] = "destination-123"
write.(buffered_event, buffer_stream_name)
local_properties
are not follow
ed, so when we got the event that let us move these messages to their ultimate location, we were safe to use follow
: