-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Messenger] Passing stamps to message Handler #31075
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This has been proposed several times, but right now we always figured out that such info should be inside the message, if they are needed in a handler. Does that make sense? If not, why? |
It does make some sense but ultimately these things are still sort of metadata and not a direct part of the Command or Event. Moreover they are usually only added to the message later and not right away. Adding such metadata as a Stamp makes more sense then creating a new instance of Command/Event (because those are obviously immutable). I did store them in a For example in the regards of Event Sourcing I found out that I very much dislike the concept of CommandHandler classes that load the aggregate identified by the command from EventStore, call a method on that aggregate to generate new events and save those events to EventStore again (such as this example from Prooph). This was exactly the same useless code over and over in all CommandHandlers which also became difficult to test as a result. So I got rid of CommandHandlers completely and have one handler that handles all commands. Now when refactoring the application to symfony/messenger it would make sense to refactor this command handler to a Middleware and have the aggregates themselves become command handlers. The middleware would load the current aggregate state, add it as a Stamp and send it to the next Middleware (HandleMiddleware) and after the inner middleware is done it would save the events from HandledStamp to EventStore. Does this make sense? The catch of course is that the handler called by HandleMiddleware would need to have access to the AggregateStateStamp - which is currently impossible. Note: In my case AggregateState is a value object separate from the class with the Aggregate's logic. This was not the case in many EventSourcing examples but it works really well for me. AggregateState has an apply method for each Event while Aggregate has methods that receive command + AggregateState and yield events. |
why not transfer stamps from the envelop to its message? Or fill pure message properties with it? I tend to believe a message handler should remain scoped to a message. |
I believe I already answered that with this:
|
hm, maybe i misunderstood
that's exactly what i proposed; handle the message using e.g. At least i think the user should be responsible for coupling domain code with infrastructure, or it should be possible to opt-out, if we make a move here. |
Yes but then the
|
We could pass the envelop along i guess, maybe using a |
Yeah, I'm interested in that too. I do understand the reasons against passing the envelope and stamps to some extent so I think I'll use my own HandleMiddleware to pass the envelope for now. I do dislike the coupling between messenger and my own code. Maybe I'll come up with something else later. No need to pollute symfony for now. Thanks for your thoughts. |
i disliked when either the message or handler is coupled to a stamp, it makes it much harder to port. Hence i suggested pure message properties / or keep a specific infrastructural middleware. Of course the porting is very hypothetical, but im not sure it legitimates Symfony to couple handlers by default. |
Yeah, that makes sense. Thanks for your input. I'll try to think more about how to decouple things on my side. Will reopen this if I figure out something. |
@ro0NL An idea just occurred to me. After reevaluating my use-cases it seems that I don't actually need different stamps in different handlers. All my cases like that make more sense as middlewares. For handlers I just need to pass the message itself + an application-specific context which will be present in some stamp but not the message itself. So a possible solution would be for the I think I'll experiment with this next week. Thoughts? |
i see :) that could be worth exploring ... it's a bit like controller action arguments IIUC. However i think Would wrapping your message, in another message of yours, be more clean? |
Since the diversity would be caused by custom, bus-specific callback, I don't think it matters too much.
From the purely academical point of view, possibly. From practical point of view, definitely not because I'd have to unpack the message in every handler and annotate / assert the objects for IDE to know the classes etc. |
or unpack from a middleware, which brings us to your proposal i guess :) i agree this creates custom (local) message handlers that follow a different semantic; but by choice π |
So adding an optional |
This PR was merged into the 6.2 branch. Discussion ---------- [Messenger] Add HandlerArgumentsStamp | Q | A | ------------- | --- | Branch? | 6.2 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | Fix #31075 | License | MIT | Doc PR | symfony/symfony-docs#17174 As discussed in #31075 sometimes it's desirable for the messenger handler to receive additional argument than just the message itself. I understand the voiced concerns about passing the entire envelope but instead of that we could use the approach from this PR which doesn't add any additional arguments by default but is actually even more powerful since it gives the user full control what should be sent to the handler if desired. This is just a prototype of course. With #45377 in mind I used a readonly property from PHP 8.1 but of course such details can be easily adjusted. Let me know if such feature is wanted in Symfony. If yes then I'll add tests and a doc PR. Commits ------- d081267 Add HandlerArgumentsStamp
Description
When working with symfony/messenger I sometimes find myself implementing a message handler where I would need some of the stamps that are attached to the message. Currently the HandleMiddleware only passes the message itself but there is no way for the handler to get the stamps. This is forcing me to rewrite such handlers to middlewares.
Example
I'm trying to use Messenger for CQRS + Event Sourcing. So I add stamps like event id, aggregate type, some data about the user who initiated the action etc. In some cases the CommandBus or EventBus handlers need the data about the user or aggregate.
Solution
In my opinion the handler should receive an array of stamps or possibly better the Envelope class as second argument. What do you think?
The text was updated successfully, but these errors were encountered: