Getters for Aggregate's attributes

Is it a good idea to expose getters for Aggregate’s attributes so that copying the domain state to the Events can be off-loaded to MapStructs?

First and foremost, welcome to the forum, @linkedsg!

I would suggest against doing this, @linkedsg. The Aggregate is intended as your “decision-making model,” whereas the projections are there to serve the questions. Getters typically are in place to answer questions to your system, not to deduce whether a command should succeed.

Differently put, the state within a (typical) aggregate does not reflect 1-on-1 to what a projection serves.

Granted, this suggestion stems from the fact that you want to use Command Query Responsibility Separation on your models. If you very clearly don’t, then you can merge your command model (the Aggregate in Axon Framework) with the query model.

However, I personally believe there’s great value in that model separation, as it makes it so you can optimize for their exact use cases a lot better. Hence why I recommend against placing getters on your Aggregate.

Hope that helps, @linkedsg!

Thanks for the response Steven.
I’m trying to keep the Events as the source of truth so I was creating my events with all the state of my aggregate + the relevant command data. Is this a bad idea?

That sounds like you want to do event sourcing; I am all for that! And I think you’ve come to use the right framework to help you out with that. :wink:

However, we tend to suggest you combine this with dedicated models for dedicated purposes. Axon Framework’s aggregate support is there for the decision-making logic. Differently put, to validate your writes, represented as commands. This makes it so that you can frame the aggregate as the command model.

Furthermore, the command model should be optimized for making decisions.
That does not reflect the need for getters. Instead, the command model should receive a command and decide to publish events on that. That’s all you’d expose. By doing so, the command model decides which occurrences (read: events) become part of your source of truth. Then, to change this flow into event sourcing, you would add event sourcing handlers to the command model to recreate it.

For “getting” information, you would construct a projection (or, if we stick to CQRS terminology, a query model). As you want your events as the single source of truth, we should (re)construct the query models based on the same events that (re)construct your command models.

Thus, by driving both command and query models to be constructed based on events, you get what you’re after. If you’re new to this flow, it might be worthwhile to take the first two courses from our academy, by the way. Those will give you the basis of making an Axon Framework application, with some terminology to help you further on top.

Will try that. Thanks Steven