What's an Aggregate

An aggregate is a cluster of domain objects (i.e: entities and value objects) that can be treated as a single unit.

It's a Domain Driven Design's tactical pattern and represents a transactional boundary. This means that the aggregate covers the the limits of any transaction in a microservice, so that as part of a transaction you retrieve and save the whole aggregate.

One of its components is the aggregate root, and any external reference to a specific aggregate goes to the aggregate root. This means that the invariants are encapsulated and therefore protected because an aggregate does not expose its state. In fact, when using CQRS, aggregates only expose behaviour, business methods that are invoked and will produce (or not) events that, once applied, will internally mutate the aggregate's state.

I know, I know, this all sounds very abstract and it's actually not so difficult to understand it once you see it. There is a brilliant series of articles written by Vaughn Vernon in which he explains this in a more concise way and shows some examples on how to properly model your domain with aggregates so that every transaction touches, at maximum, the whole aggregate and no more.

In other words, if you model your domain in a way that a single transaction (initiated by a command) ends up requiring to modify more than one aggregate, you've done something wrong and should rethink your model. Remember that an aggregate defines the boundaries of a transaction and, unlike with CRUD systems that use (and encourage) anemic models (an unfortunately common OO anti-pattern), a transaction does not need to update several domain objects, just one, the aggregate.