Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CQRS: How to implement a voting mechanism (many to many relationship)

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

  • UserId
  • ProductId

Some possible solutions that I have found:

  • Use a deterministic GUID based on the userId and productId
  • Votes are a list of aggregates on a product
  • Create a voteId and use that to delete the vote.
  • Store the aggregate as a string and use a combination of productId and userId

What would be the best approach?

like image 840
Valderann Avatar asked Jul 24 '17 08:07

Valderann


1 Answers

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).

like image 148
Constantin Galbenu Avatar answered Sep 28 '22 10:09

Constantin Galbenu