I'm rather new to CQRS and DDD and am wondering what would be the best way to implement a voting mechanism in the domain model.
On a product, a user can upvote/downvote. There are some domain rules regarding voting, f.e. you can only vote once, either down or up.
Both vote and product would be an aggregate root. Is this the best approach? It's recommended to keep the aggregates small. Adding the vote to the product aggregate root would overtime make it bloated.
The issue that I'm struggling with is deleting a vote when the vote is an aggregate root. You need to know which vote aggregate needs to be deleted. It's not possible in the command handler to retrieve the vote from the repository with the productId and userId. The aggregateId is stored as a single Guid in the database.
The command would contain these fields
Some possible solutions that I have found:
What would be the best approach?
Using my limited understanding of your domain, I can conclude that there are two bounded contexts Catalog
and Reviews
. In this case, you could have a Product
aggregate in the Catalog BC
and one Product
aggregate in the Reviews BC
.
The Product
aggregate from the Reviews BC
would contain a list of all Vote
entities for a particular product. A Vote
entity would contain all the information needed in order to enforce the vote only once
business invariant (like IP address, user ID etc). Both Product aggregates types (from the two BCs) would share the same ID - that's how you keep them synchronized, if you need (for example when a product is removed from the catalog it is marked as non-votable in the reviews BC).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With