Command validation in aggregate, evolving multiple aggregates

Hello!

I am new with ES and Axon and I am building an app that have two aggregates, lets call then Forum and Topic. Forum have a list of strings, that are used to validations, and Topic have a command handle that need to validate a command field based on that list in Forum aggregate. See the code bellow for example:


public class CreateTopic {

    @TargetAggregateIdentifier
    private String topicUuid;

    private String topicName;

    private String forumUuid;
}

@Aggregate
public class Forum {

    @AggregateIdentifier
    private String uuid;

    private List<String> topicNames;

}

@Aggregate

public class Topic {

    @AggregateIdentifier
    private String uuid;

    private String name;

    // other fields

    @CommandHandler
    public Topic(CreateTopic command) {
        // need to validate if the father aggregate A contains a children with that name
    }

}

The problem is that the Forum doesn’t existis until their first child Topic is created. I did not want to have to check in the database if this forum does not exist and send a create command if it does not exist, just get an empty one with the UUID if it’s the first time it is being used, perhaps a createNewIfAbsent method in AggregateLifecycle was useful here. External users doesn’t even need to know the existence of the Forum inside that application because they just want to create a Topic (they send me just the Forum UUID, and nothing else related to the Forum), but I need to validate if there are any Topics inside that Forum with this topic name, and tell the user “there is already a topic with this name and forum” if that rule is violated on the topic creation.

I don’t know the proper way to validate that rule. At the moment, I am just ignoring the “Forum” aggregate, and calling a projection of Topics (by the query gateway) inside the command handler just to check if there is a topic with that name and forum UUID in the database. I think it isn’t the best way. Any suggestion?

Do topics really exist as their own aggregate (bounded context)? Or aren’t they merely parts of a forum? In that case, you could read about MemberAggregate … and handle your topics from within the forum aggregate.

Hello!

I read something about MemberAggregate, but the problem would be the creation of the Forum aggregate. As I said, I would’t like do explicitly create the Forum aggregate, because I don’t want it that complex. In that approach, in every topic that the user creates, I need to send a CreateForum command, and ignore the “Aggregate Already Exists” exception, if it happens, and then send the CreateTopic command, right? There are some way to say Axon to create the root aggregate if it does not exists?

Hi Rafael,

This to my sounds like set validation, which Daniel Whittaker does a decent job on explaining it right here.
For now, what you’re doing is actually a fair approach: first query a very concise query model containing just the existing topics.

If it’s already there, you just immediately return it’s existence and otherwise you issue a CreateTopicCommand to initiate the Aggregate.

We do agree with your suggestion by the way: it would be great if Axon would be able to cover the scenario that a given Aggregate already exists.
The works to introduce this logic is already captured in an issue too.

So for now, I’d likely stick with the approach you have.
In the mean time, you could monitor that issue if you want.
I assume we’ll be picking it up somewhere soon.

Hope this helps you out Rafael!

Cheers,
Steven

Thank you Steven!! This approach with query is working without problems. Any way, I will monitor this issue as you suggested. Thanks again!