We have a set of discrete, long lived clients. Each client (unfortunately) has an identifier that is just simply their name as a String, like “ABCorg”. It is by this name that the consumers of our API know how to communicate which client to us.
Originally, we created singleton aggregates, one for each client, to keep track of their payment settings (and also perform tasks like queueing). The identifier for these aggregates were just their name, ie “ABCorg”. As each payment aggregate came due, it would have to transact the settings aggregate for the client that it was ascribed to so as to know the correct settings to apply.
Now, I am having to create more settings for each of the clients, but these new communication settings don’t relate to payments. I wanted to create separate singleton aggregates for these new settings, but then realized that the AggregateIdentifier would be the same (ie, “ABCorg”), and I cant have a PaymentSettingsAggregate with an id of “ABCorg”, and a CommunicationsSettingsAggregate with an id of “ABCorg”.
Are there any recommendations for how to handle this situation in DDD/CQRS/Axon?
My current solution has been to group the commands by functionality (ie all the payment settings commands in one package, the communication settings commands in another), and then put the @TargetAggregateIdentifier on a method in the command that will generate the ID. Then I take the client name, and append a suffix that identifies the settings aggregate it belongs to, ie
ABCorg_PaymentSettingsAggregate would be one ID and
ABCorg_CommunicationSettingsAggregate would be another ID.
That way, the consumers of the API can still just send “ABCorg” as an identifier, and I can append the rest of the ID on the fly to send it to the correct settings aggregate.
The annoyance of this approach is having to remember to idempotently append the suffix on request, and idempotently remove the suffix on response.
Also, if this is an acceptable approach, the other issues I have found is that the @TargetAggregateIdentifier method of the commands is not called in the tests when comparing the commands. As such, if the client name was supplied as “ABCorg” on command creation, then during the test it will compare “ABCorg” to “ABCorg_PaymentSettingsAggregate”, and the test will fail. Recommendations?