Aggregate with constant id

Hello, im quite confused nowadays with the DDD principles, to put it compact i’ll use simple example:

Consider the validator aggregate which validates some commands, this validator needs to keep consistency with the configuration values, lets say i have validator for submitting a post, if user wants to submit a post it is whether the last submission date (for all of the requests) is greater than 30 seconds.

`
Validator {

lastSubmit: Long
minDelay: Long

void handle(changeConfig:NewConfig){
apply(configChanged)
}

void handle(validatePost: Post){

if (currentTime - lastSubmit < minDelay){
apply(success)

}

}

void on(evt:ConfigChanged){
minDelay = evt.delay

}

void on(evt: PostSuccess){
lastSubmit = currentTime

}

}
`

Now, as you can see that such aggregate is a single instance here, it doesn’t have multiple aggregate instances.
I’m familiar also with domain services, which could be used in this scenario but i’ve also heard about anemic domain model? It’s like even if i do implement it with domain service approach i would need to store the config somewhere and i dont’t really enojoy the idea that i would need to create specific database entry for it when i could just use axon’s aggregate repository to store it.

So it comes down to two questions:

First, are the domain services good approach for such things? Even if how to keep it simple, and make sure that consistency is kept between changing some rule and checking it.

Second, if i can create the aggregate such that, how would i make sure that only one instance of it is handled, eg what is the good spot to initialize it with some static aggregate id or maybe make the commands without aggregate id but how would i easily create the aggregate with constant id on demand when client sends the command?

At this moment im initializing the aggregate with constant id when my application starts (it obviously fails to create aggregate on each succeeding restart, but that’s intended) and every command targets that constaint id.

Many thanks!

An aggregate is an entity (viewed from outside) and is identified distinctly by an id.
It has an own instance for every Id. If there will ever be only one of it, something may be wrong.

An aggregate is also a boundary, grouping and managing detail entities and their state inside.
It should have a name from the Domain like „Account“, not a technical thing like a validator.

Validation should be made where state is about to be changed.
This is right inside an entity or aggregate, triggered by a command and before the event is published.
It may be necessary to use a service for (complicated parts of the) validation, if e.g. other services needs to be orchestrated for that. One solution might be a command handler.

Hi Robert, Johnny,

The ‘Validator’ Aggregate you’re sketching, Robert, doesn’t feel entirely right to me.
It’s fair to have a command handler to adjust some configuration, which applies an event if the timing is right.
Axon however does not force you to have command handlers on Aggregate instances alone.

You are entirely free to have an @CommandHandler annotated method on a regular Component, like described in this section of the Reference Guide.

Like Johnny point’s out, if you’re having a single Aggregate instance for a given Aggregate, that might signal something’s wrong.
Having such a set up is what we typically call a ‘system Aggregate’.
Thus an Aggregate which has only one occurrence, used by the entire system.
Stating it as such already makes it seem more like a service for validation rather than an Aggregate.

I understand it’s nice to reuse the Aggregate Repository to store the “lastSubmit” and “minDelay” fields in apposed to providing another means of storage.
However, I still think that’s what you’ll have to do - provide another means of storing that information.
Whether that’s persistent storage or ephemeral highly depends on your application, so I’d be hard pressed to tell you which of the two should be done.

Regardless, hope this helps!

Cheers,
Steven

Hey Steven,
Thank you for your perspective on the issue.

I forgot to mention that yes, I’ve solved it by using domain service + command handler, meaning in my scenario command handler is an application service which delegates the work of changing the active configuration to the domain service, and the domain service takes care of the persisting.

It has been quite a while for me to trying to understand this whole DDD concepts and i think that I’m on right track because as you both mentioned, ‘it feels weird’ having single aggregate starts having big sense.

The issue perfectly fits into the domain service approach the problem with my thinking was that I was scared of introducing anemic domain model but in such scenario i think it is just fine.

So thank you both :slight_smile: