Don't publish Domain Events, return them!

During a discussion around some of the code examples in Vaugn Vernon’s book Implementing Domain Driven Design we got stuck at what first appeared to be a tiny detail: where the domain events are published. Is it part of the domain or not? But more importantly, what is the programming model for publishing events? I think this issue highlights how object oriented programmers are so used to carelessly mutating state that they don’t even consider any alternatives. I will not go into monads or anything, but only show how using normal return values can simplify your code.

In many DDD examples of code that generates domain events you often find a EventPublisher (or MessageBus, DomainEventsRaiser etc) that is injected into the domain object or worse accessed statically as argued by Udi Dahan. The aggregate then use the EventPublisher to send all the events that are generated when processing the command. When reading the code many people think it is very clear and easy to understand. However, there are many problems with this approach.

I will use my current favorite domain rock-paper-scissors. For a more complete example that also uses event sourcing, have a look at Aggregates + Event Sourcing distilled. (In the following example I will not use event sourcing and will in fact mutate state directly in the command handler. The reason for doing this is that in this blog post I target traditional object oriented programmers. If you are already into functional programming, you should probably read Event Sourcing in Clojure instead.)

The idea is that once the game is started either player can make their move first and when both players have made their move the game is over.

Can you spot the bug?

No event is generated when “lastMove” equals “move”, that is no GameTiedEvent is generated! Since the event publishing for the winning event occurs in a separate method it can be easy to miss this.

First, we write a test case to try to find the bug:

To make the test work we need to do the following:

  • Know that events are published
  • Create an EventPublisher and inject into Game
  • Remove all events after the first command since we don’t want to verify these

Since the test fails you start the debugger. You step over the first “eventPublisher.publish” method in the debugger and then think to yourself “hmm, the MoveMadeEvent have been published, maybe it is a concurrency issue. Maybe somewhere else some weird behavior is triggered by this MoveMadeEvent”….

However, as you will realize after an hour or so of debugging is that the event has not at all been published. The EventPublisher only publishes the events when the entire command has been processed! Otherwise the command will not be atomic! This is typically setup in the Application Service that start the transaction.

Of course, one solution to this is rename the EventPublisher to EventTracker or something, but that is only a workaround and still makes it hard to understand for new developers what is going on. Even worse, since your domain depends on this code it means that you might have to explain event publishing/tracking to a domain expert. From their perspective event publishing/tracking is a technical detail that they couldn’t care less about.

Now lets consider a revolutionary new approach: use return values! :-)

Implementing the Game logic becomes:

Immediately we get a compiler error saying that generateWinningEvent is missing a return value! Let’s fix it:

And the test case:

The domain has no knowledge about event publishing or event tracking. The test only have to check the return value it cares about. Clean and simple. It is easy to understand and easy to test.

But a Command returning values, isn’t that a violation of Command Query Separation? Or perhaps Tell, don’t ask? Perhaps, but the reason is not the fact that I’m returning events, instead the reason is I am returning events AND mutating state. By using event sourcing you separate the mutation to when the event is handled. But, it gets even better. Event sourcing is not object oriented, instead it is functional. Then “Tell, don’t ask” does not apply as it is a object oriented advice. Michael Feathers also talks about Tell above, ask below as a way to combining OO and functional. Another good point is made by Robert Harvey:

If you are using the result of a method call to make decisions elsewhere in the program, then you are not violating Tell Don’t Ask. If, on the other hand, you’re making decisions for an object based on a method call to that object, then you should move those decisions into the object itself to preserve encapsulation.

So where are the events actually published? In the Application Service of course:

This code is just boiler plate, see Aggregates + Event Sourcing distilled how you can in fact use a completely generic Application Service for all command handlers using aggregates.

Sure, there are cases where injecting something like an EventPublisher or even accessing it statically may be useful. However, typically this is because you are either writing your own framework or working around someone else’s framework. I hope I have convinced you how normal return values can be a lot simpler and easier to understand!

This Post Has 35 Comments

  1. events is not business, so when in a business method return
    events, it intrudes business logic.

    1. Not really sure I understand what you mean. Domain Events are part of the Domain by definition, so clearly it is something the business cares about. Why would it intrude on business logic?

  2. These methods do too much IMHO. How about separating the logic of the actual game in one class and event handling in a decorator?
    The return value of performMove should be a class Result with an Outcome enum (move, win, tie) and the player id as attributes. That is pure domain logic.
    The decorator then has enough information to create the MoveMadeEvent from the passed arguments, if there are no exceptions, and the result events from the return value.
    The EventDispatcher can be injecting into the decorator without affecting the domain objects.

    1. Did you look at the other blog post “Aggregates + Event Sourcing distilled” ?

      I agree that these methods do too much, but by removing the state manipulation you only return one or two events (MoveMade and perhaps GameWon or GameTied) which is very similar to what you are proposing.

      The difference compared to using a separate Result class is mainly a matter of explicitly restricting the number of possible return values, ie a question of static vs dynamic typing. Instead of returning a List of Events, you can only return the specific outcomes ie:
      * OnlyMoveResult = 1 MoveMadeEvent
      * WinningMoveResult = 1 MoveMadeEvent + 1 GameWonEvent
      * TiedMoveResult = 1 MoveMadeEvent + 1 GameTiedEvent

      hmm… sure, why not! Instead of using a decorator you could do something like this:

      Although it creates a bit more boilerplate I can see the value of doing something like this. However, personally I prefer the solution in Clojure and then this extra static typing info is not needed.

  3. If you really wanted to be sure to cover all events, you’d have an else without an if at the end. To expect that the code as it was written covers all cases is stupid.

    1. Sure, but many mistakes are stupid once you see them. The point is that by using a return value you are forced to write correct code.

  4. Great post, thanks for that – I was struggling to incorporate domain event publishing into my AR, and it felt all wrong. But an aggregate method that takes a command and returns a maybe-empty Seq of domain events seems both cleaner and logical, and much easier to dispatch to a publisher, wired into an app service, for example.
    And yeah, following V.V.s book, we have domain experts talking about events that happen in their domain, nothing techie there.

  5. That is an interesting situation. In my opinion, you need to return an object when clients expect a result. In this simple scenario returning the events works fine but in a more complex situation this will easily fail i.e. think in the typical example where you are processing an order end the output is an invoice but also have to deal with the events.

    1. What I’m talking about is the implementation of your domain code. If you have a REST API that is calling your domain logic, of course you can return whatever you want from that. The best approach is by doing a projection of the domain events.

      My point is simply that you should make your domain logic free from side-effects and put the side-effects on the outside.

  6. I would imagine it would be easier on your infrastructure so add these events to list then have a separate method to get that list. That way each controller action does not need to wire into every method you call on the model. This is in fact what most event sourced cqrs systems do. One of the main points of calling the publisher directly is that you are piping though a common interface where infrastructure can be easily plumbed, instead of into the wide world where you get no infrastructure support.

    1. Yes, I know that many cqrs systems do this in a different way. However, I believe my approach is better! :-)

      • Adding events to a list? A separate method for getting that list? Sounds like a lot of mutation going on. I really don’t like that. It makes my programs harder to test and very difficult to make them thread-safe.
      • Easily plumbed? Actually no. You have to use dependency injection or some kind of singleton. Sure, not super hard to do, but compared to not doing anything at all it is definitely more work. Have a look at my blog-post about Aggregates + Event Sourcing and in particular the ApplicationService implementation
  7. Thanks for this post. Recently i read Vaugn Vernon’s book Implementing Domain Driven and had similar question in my mind like dependency injecting publisher to aggregate will make testing harder and seems more coupling. This makes more sense.

  8. Thanks for this eye-opening blog post. This is an elegant and obvious (once someone tell’s it to you) solution to the problem.

  9. Why not go one step further and have the “service” be a function that returned them then you could get something like …

    MyCommand : StartTransaction |> EnrichContext |> ProcessMyCommand |> Publish



  10. Thank you for this.
    In my view, there is a “semantic” issue designing api where the “client” asks you to do something and you return events to him… I prefer to see a Listener in the signature where you can be notified about events.
    And I think this is also simple to design it using TDD…
    What do you think, Jan?
    Thanks Bye

    1. As I mentioned in previous comments the client of the domain is the application service, not a client application. Since the Application Service is responsible for the transaction and other infrastructure concerns, I think it is perfectly reasonable that the domain returns events. The Application Service asks the domain (aggregate) : “What would happen if this command would be executed given the current state?”, the domain replies “These events would occur!”, and the Application Service commits by saying “These events occurred at this time”.

      My goal is to keep the domain code as clean as possible, ie avoid all infrastructure and cross cutting concerns. For example if you want a Listener, then you probably want this for all commands. By moving the responsibility to the Application Service you can easily have a listener for all events. Have a look at this blog post for a completely generic Application Service:

  11. I like this approach of returning events instead of using an event publisher, but what about situations when your domain method needs to return something else?

    Take Udi’s article: and imagine that you want to create a Shipment out of an Order. The correct way to do it would be to call order.createShipment(…) which would need to return the newly created Shipment.

    1. My guess is that Udi Dahan uses the old definition of aggregate and not the one updated by Eric Evans just a few months earlier to Udi’s post. The new definition and the one I’m using is to view aggregates as “consistency boundaries for transactions, distributions and concurrency”. The way I implement this is by not allowing the clients to interact directly with the aggregate code. Instead the client sends a command that is handled by an application service that creates the transaction and delegates to the appropriate aggregate. All the aggregate does is return the domain events that should be published.

      I could allow the Order aggregate to return a ShipmentCreatedEvent(shipmentId) and thereby creating the Shipment. However, notice that all events that are returned must have the same aggregate id otherwise this would violate the definition of an aggregate as a consistency boundary for the transaction. The more “correct” way would be to return a OrderShippedEvent(orderId) and then have a saga convert this into a ShipmentCreatedEvent(shipmentId, orderId) (the first attribute being the aggregateId).

      Also notice that in the client code you can have all the utility classes or DSLs you want. That is, if you want to write your client code as order.createShipment(...) then that is ok, but the order object is not the actual aggregate implementation. Instead this order class would look something like this:

      a more modern version using RxJava might look like this:

      Hope this explains how I think!

  12. What about situation when Game has a timeout and you want the Game instance published TimeoutEvent after some period of time? One way is to have a service that holds a collection of timers but I think this is not right as TimeoutEvent is a business rule, i.e. it is a part of business logic, and should not be in Application Layer (Service Layer).

  13. I’m trying to wrap my head around the same scenario (not injecting or statically referencing an “EventPublisher” in each model). But I’m kind of struggling with this notion of returning the events as the result of a “command”. To me, returning an arbitrary array of events feels like you are embedding an event model into the business logic. I also wonder what happens if you need to return something from the command:

    Receipt = account.deposit(fromAccount, new Currency(20, Currencies.USD));

    Are you saying I should wrap the receipt in one of the domain events? Maybe in something like a DepositEvent? If that’s the case, it may make sense if (and only if) one event is returned. But still it kind of seems funky.

    Alternatively, I was wondering what you think of using a traditional Listener model on the class and bubbling up Global events from an attached listener? (excuse my Java, it’s been a couple of years)

    public interface EventProducer {
    void addSubscriber(Subscriber subscriber);

    class Account implements EventProducer {
    public Receipt deposit(Account fromAccount, Currency amount){
    // ... DepositEvent(this, fromAccount, amount);
    return receipt;

    Then you can subscribe to domain events by subscribing to the model.

    Alternatively, in languages supporting AOP, we could use method interceptors to interpret results from method calls can create Domain Events (though to me that seems an unnecessary separation of Domain Events from the model).

    Truly curious what you think; and by the way great article – I love it when programmers can have these kinds of discussions.

    – Richard

    1. There are a couple of points I would like to make:

      1. Clients are not supposed to call the command handler directly. Instead the application service should handle client requests and turn them into commands that may have a response. Understanding the difference between command handlers and application service and their different responsibilities is crucial.
      2. If you want to return a receipt what you probably want is to create a receipt, which would actually require an event, for example ReceiptCreatedEvent. Otherwise there would be no record of the receipt.
      3. I think the Listener model you are proposing is exactly the same thing as an event publisher.

      Hope this helps!

      1. Jan,
        Like Roc, I’m back! Over the course of two years, I’ve had shifting views on how to implement this scenario. I’ve generally converted to the idea of returning events, however, I’m curious about how you implement persistence in this pattern? Are you using event handlers to save entities that change? Event Sourcing seems like the obvious methodology to use, but in a more traditional application what would you recommend?



        1. Have a look at the post Aggregates + Event Sourcing distilled for a more complete example with event sourcing. The code is available here, although only an in-memory event store.

          If you are not using event sourcing, then I don’t really have a good recommendation.

    1. The constructor is the technical way that objects gets constructed in Java. I think you need to separate that from the command that is creating the aggregate in your domain, ie you need to have a command handler method for this.

  14. For more than two years I’ve been revisiting this blog post. As an OO programmer, it wasn’t until I’ve become interested in functional programming that this post means something to me.

    Excellent work here!

  15. Your approach is good but I like to modify it a bit, instead of returning events I would prefer to save them to transient field on aggregate. This is not my idea I borrowed it from: This way you may subscribe for some Hibernate event/add listener and handle publishing events for all entities automatically.

    1. The whole point of this blog is that I want to avoid solutions like that. By having pure functions your code will be much easier to both understand and test.

  16. This is a great ideea. My problem was that during my DomainService execution I was firing some events, like OrderStatusChange, OrderChange. One problem was if there was a database error: my sql operations were in rolled-back , but some jobs were already into the air: for example a job of sending mail for status change (as a listener os OrderStatusChange).

    In this way I can rollback or commit my database in the Application Service Layer in the same time with firing or ignoring my events.

    One downside is that using my Domain does not imply that events are fired, so some “domain logic might be broken” – that logic that depends of event-wiring

  17. Oh please! Don’t generalize a particular solution to a particular problem. Definitely not by “targeting OOP programmers”. And conveniently breaking another pattern (CQRS) just to justify your own solution? Those are telltale signs of a bad design and implementation.

    1. CQRS is not broken as it is an architectural pattern for how to structure your application and not about an individual class or module.

Leave a Reply

Close Menu