Giter Site home page Giter Site logo

Comments (8)

mbadolato avatar mbadolato commented on July 24, 2024

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 to MetadataEnrichingEventStreamDecorator to decorate the messages
  • MetadataEnrichingEventStreamDecorator will call out to the registered Metadata enrichers to do the enrichment
  • EventSourcingRepository 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.

wjzijderveld avatar wjzijderveld commented on July 24, 2024

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.

mbadolato avatar mbadolato commented on July 24, 2024

@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.

wjzijderveld avatar wjzijderveld commented on July 24, 2024

@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.

mbadolato avatar mbadolato commented on July 24, 2024

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.

mbadolato avatar mbadolato commented on July 24, 2024

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.

wjzijderveld avatar wjzijderveld commented on July 24, 2024

@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.

wjzijderveld avatar wjzijderveld commented on July 24, 2024

Closing this issue for now, feel free to reopen if you want to discuss it further.

from broadway.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.