Comments (8)
So, I finally got a chance to research a little more and figured how the Metadata system works (via decorating). If I'm understanding correctly:
- Register Metadata Enrichers
EventSourcingRepository
will call out toMetadataEnrichingEventStreamDecorator
to decorate the messagesMetadataEnrichingEventStreamDecorator
will call out to the registered Metadata enrichers to do the enrichmentEventSourcingRepository
then does its thing to append and publish
So far so good?
I'm still thinking I see an Interface issue, however.
MetadataEnrichingEventStreamDecorator::decorateForWrite()
is defined as follows:
public function decorateForWrite($aggregateType, $aggregateIdentifier, DomainEventStream $eventStream)
{
if (empty($this->metadataEnrichers)) {
return $eventStream;
}
$messages = array();
foreach ($eventStream as $message) {
$metadata = new Metadata();
foreach ($this->metadataEnrichers as $metadataEnricher) {
$metadata = $metadataEnricher->enrich($metadata);
}
$messages[] = $message->andMetadata($metadata);
}
return new DomainEventStream($messages);
}
The $aggregateType
and $aggregateIdentifier
variables are never used anywhere though. To me, it would seem appropriate to pass those along to $metadataEnricher->enrich(...)
so that the enricher can make use of them.
Perhaps we have an IPAddress enricher but we only want to add that IP Address as metadata to comments someone leaves on a post, for example, so the enricher would need to look at $aggregateType
to determine if it should enrich the metadata with the IP Address.
Looking at MetadataEnricherInterface
, the enrich()
method is defined as
public function enrich(Metadata $metadata);
So, do we need to update that interface to require $aggregateType
and $aggregateIdentifier
and update MetadataEnrichingEventStreamDecorator::decorateForWrite()
to pass them along?
from broadway.
Sorry for the late response, somehow I didn't get an email from Github when you created the issue.
So far so good?
Correct :)
In this implementation of EventStreamDecoratorInterface
the $aggregateType
and $aggregateIdentifier
isn't used, but there is an example in the tests where they are used: TraceableEventstoreDecorator
A MetadataEnricher shouldn't have knowledge about the Aggregate in my opinion, it just needs to add metadata to a DomainMessage, without the need to know exactly where it applies the metadata to.
If you want to limit certain enrichers only to specific AggregateRoots, you should create and configure an EventSourcingRepository with specific decorators for that AggregateRoot.
from broadway.
@wjzijderveld Makes sense, thanks for the reply.
I was able to successfully get the metadata working last night in one of my tests. One thing I noticed though was that upon dispatching a command, the metadata was not yet decorated on domain message when the message was sent into the Projector.
The metadata got saved in the DB event store no problem, and was available when subsequently calling load(...) to reconstitute, it just wasn't available at the point in the process where the projector's MyProjector::applyMyEvent(MyEvent $event, DomainMessage $message)
receives the $message
. Should it be available there? Thoughts? (Sorry, I'm still relatively new to Event Sourcing and still working thru how some things function together)
from broadway.
@mbadolato I see, not sure if that should be possible. You shouldn't need the metadata in your projectors, as it is not part of your domain (it is just metadata). Do you have a specific use-case where you want the metadata to be available in a projector?
from broadway.
No particular use case yet as I was just playing around with it. I guess I was figuring something like metadata being the logged in user and/or IP address and possibly that information needed to be exposed somewhere (reporting etc) but it was not necessarily part of the domain itself.
Like I said, no use case or need, I was just figuring that it would have been exposed since the projector takes the DomainMessage and if access to the metadata was needed for some reason, it would be there. I guess, if it's not available in the projectors, which we use to build the read model/views, when/where would be the appropriate to access the metadata that was captured?
Again, maybe my understanding of the concepts of what it should be for are not correct, as I'm still new to using event sourcing.
from broadway.
Just happened to be reading some of the info for EventStore (the product Greg Young et al developed) and came across this:
Every stream in the Event Store has metadata associated with it. Internally, the metadata includes such information as the ACL of the stream and the maximum count and age for the events in the stream. Client code can also put information into stream metadata for use with projections or through the client API.
https://github.com/EventStore/EventStore/wiki/Stream-Metadata-(HTTP)
from broadway.
@mbadolato At Qandidate we don't use the Metadata directly. Among other data, we store some info about the request for troubleshooting purposes.
ping @qandidate-labs/broadway anybody else has an opinion about this?
from broadway.
Closing this issue for now, feel free to reopen if you want to discuss it further.
from broadway.
Related Issues (20)
- drop test/Broadway/TestCase
- make PHPUnit a dependency HOT 5
- test the test helpers with examples HOT 2
- Built-in asynchronous way to run processors? HOT 3
- Example/explanation on event sourcing for aggregate roots HOT 1
- What is the overall state of the project? Is it GDPR ready? HOT 2
- Simple Command Bus - Manage Throwable exceptions
- Could you do a new release? HOT 2
- Are there any plans to update broadway? HOT 1
- Asymmetry between EventBus interface and EventListener interface HOT 2
- Broadway does not seem to survive hot upgrades HOT 2
- duck-typing vs interface HOT 1
- Replaying events to rebuild elastic search index HOT 1
- PHP 8 support HOT 2
- Processor after projector HOT 2
- Aggregator HOT 3
- Indirect development dependency used in src ConcurrencyConflictResolvers
- no recent tags? HOT 1
- Get uncommitted events without empty the aggregate HOT 4
- Give serializers flexibility to map based on event type
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from broadway.