Some Questions on DDD, Axon and AxonTrader

Hi

  1. Vaughn Vernon says that aggregate should only hold references to other aggregates if they need to communicate. I understand that if you want an aggregate to do something you let that aggregate consume an event from the source aggregate. In the case where you want a response from the other aggregate, how will you do it in axon.

  2. If you have a business rule that has to be respected, and on executing the command, the rule is violated, how do you communicate to the query side that something went wrong.

  3. Looking at the axon trader example, the commandhandlers return a value, DDD says commands shouldn’t return values. Is it just for initializing the database or could that be used in requesting information from aggregate.

  4. Still in the Axon-Trader application I see Model being used a lot in controllers. I don’t know about the Model class, but it looks like kind of a session variable.
    i. Could a JavaScript framework, access the Model?
    ii. Could it be used like a session to store application information?
    iii. Can the automatic redirection (return “user/detail”) work with a JavaScript framework too or its just a jsp thing?

  5. In modelling, I understand that the database tables are just views for display convenience.Are database tables
    then required to be linked then with foreign keys?

Thanks and sorry for the long essay.

Hi Harvey,

  1. Not 100% sure how to answer this question, but I think you’re talking about aggregate roots and there entities. If you’ve got entities within your aggregate and you want to listen to the aggregate originating events in the entities, you’d just need to add an @EventSourcingHandler. Same holds if you want to listen to events which are published in an entity and other entities are interested in that: just add an @EventSourcingHandler annotated event handling function in that entity class.
    If you’re however referring to communication between aggregate roots, what you’re probably looking for is to build a Saga solution. This would require you to associate both aggregate roots with that Saga. The Saga would then typically get triggered by events from both aggregates and publish commands as a response on those events. These commands can then be handled by either of the aggregates which that message needs to go to. This could then get you the requested ‘response from other aggregate’, although that’s not what I’d call it.

  2. Could you give a more thorough use case on when you’re forced to handle an exception which happens on the command side, on the query side of your application? I can’t recall an occasion where my Axon application required to do that. A failing command due to business rules means no events should get published, so no event store adjustments. Since you’re query side relies on the event store for knowledge, a failing command on the command side means nothing happened for the query side, including exceptions.

  3. I’d suggest only using the return values of the command handlers for identifiers, not to query the aggregate itself. So that comes down to the aggregate identifier when the aggregate’s created and to the identifiers of entities you create as a response to handling that command.

  4. The Model class is a Spring Framework UI object. I’m afraid I don’t have any experience in using it, so I can’t give you any information on it’s usage. Maybe somebody else could chip in on that.

  5. Depends on if you want foreign key relations of course, but it’s not a requirement in any form from Axon. I usually don’t have any foreign key relationships in my query side views.

Hope this helps!

Cheers,

Steven

Thanks Steven for the explanation.

Hi Harvey,

  1. Not 100% sure how to answer this question, but I think you’re talking about aggregate roots and there entities. If you’ve got entities within your aggregate and you want to listen to the aggregate originating events in the entities, you’d just need to add an @EventSourcingHandler. Same holds if you want to listen to events which are published in an entity and other entities are interested in that: just add an @EventSourcingHandler annotated event handling function in that entity class.
    If you’re however referring to communication between aggregate roots, what you’re probably looking for is to build a Saga solution. This would require you to associate both aggregate roots with that Saga. The Saga would then typically get triggered by events from both aggregates and publish commands as a response on those events. These commands can then be handled by either of the aggregates which that message needs to go to. This could then get you the requested ‘response from other aggregate’, although that’s not what I’d call it.

  2. Could you give a more thorough use case on when you’re forced to handle an exception which happens on the command side, on the query side of your application? I can’t recall an occasion where my Axon application required to do that.

A failing command due to business rules means no events should get published, so no event store adjustments. Since you’re query side relies on the event store for knowledge, a failing command on the command side means nothing happened for the query side, including exceptions.

For example, in the axon bank application, when the overdraft limit is exceeded, Allard throws an exception. How can you propagate that to the UI to let the user know that the transaction didn’t occur.

Hi Steven.
Did you see my inline response?

Another example I think is That the level of authentication in axon
trader. But I don't see in this case the cycle from the frontend to
the command side and back. However I think the verification is done on
the command side right? If so how the the query side know if an
aggregate not found exception occurred, or the user credentials are
not found for example.

Hi Harvey,

A bummer, I missed that earlier.
Sorry for that!

Concerning the exception question:

Like you point out authentication/verification/assertion of commands is done on the command side of the application.
When an exception is thrown during command handling due to a false assertion, I’d typically bubble up the exception all the way to the service publishing the command on the CommandBus.
Regularly, that service is accessed through a controller, which could adjust the response it send back to the calling process based on the exception you receive.
The exception would thus bounce back as response to the, for example REST operation which was performed to publish a command.

This thus doesn’t really touch the query / event handling side of the application, as it’s not interesting for the query-side to know a command wasn’t handled.
It’s only interested in events which occurred, as that’s it’s source of truth upon which it builds views/acts.

I hope this helps explain the point a bit better.

Cheers,
Steven

Thanks Stephen. I understand better now. Not coming back to the other scenario I talked about - the custom exception (OverdraftLimitExceeded) Allard created in the Axon Bank video tutorial, is there a way to bubble up that type of exception to the controller too? I think it will be more pro-DDD to use exceptions that have a domain meaning.

Hi Harvey,

No problem! Here to help :slight_smile:
Would you could do to get your exception in your controller, is by using the CommandGateway.send(Object command) to publish your commands on to the CommandBus.
The return object of CommandGateway.send(Object command) is a CompletableFuture.
The CompletableFuture in turn has several nice chaining function to perform after the CompletableFuture has finished, so after the command handling section has finished.
Handling exceptions is one of those, which could thus allow you a nice way how to handle exceptions from the command side.

Hope this helps!

Cheers,
Steven

Nice! Thanks Steven. Got that working.

Another question on DDD. in the Red book, there’s a design example on aggregate where there’s a user aggregate having a person entity attached to it. Let’s say in your database you want a single users table (combined with Person fields), is it ok to just use Person as a value object or do you use it as an entity(this will create the Person table in the DB which I don’t really want).

Last one (I’ll be going to a DDD forum henceforth :slight_smile: )

The Red Book also talks of using events like ContactChanged, NameChanged, but on the UI, all of these could be changed at the same time. How do you do in this situation? I don’t just see how to prevent using the anaemic model.

Hi Harvey,

I’d say the answers to both of your questions are ‘it depends’.

In Axon you’ve got the possibility to let the aggregate and it’s entity get stored as database entities immediately.
But if that’s not what you require (which seems to be the case according to your response), then just let it be a value object.
You can always add a Person table latter if you’d require it; you’ve got your events after all.

The event granularity comes down to what level of granularity you require in your application.
Maybe a ‘ContactChanged’ event is super important for some process in your application, so then you’d want to apply an event on that level.
But maybe it’s not interesting at all and a ‘PersonChanged’ event is good enough.
If that’s the case, then you should go for that level of granularity.

From a UI perspective you could for example have one action to update the ‘Person’ aggregate.

From there on you could either chop up the ‘update-person-action’ into several ‘Update…PersonCommands’, or into one big ‘UpdatePersonCommand’
In the latter scenario (the big command), you could then choose to have a ‘PersonUpdatedEvent’, or split out the changes into smaller events (as you’d probably would have if you’ve got fine grained commands) within your aggregate.

Does this give some insights?

Cheers,

Steven

Yeah thanks. I went for the “big” command, though the number of setters for the database entity is really annoying for a few changes made.