Uniqueness validation when using CQRS and Event sourcing

cqrsdomain-driven-designvalidation

I'm trying to implement my own CQRS infrastructure with Event Sourcing to learn it better. As a sample project I'm implementing a blog engine, I know it might not be a perfect fit but I just want to work on something real.

The problem I've come to now is validation. Every post have a shortUrl, and the shortUrl should be unique, but where should I put this validation in the domain? I know that I will have that validation before I even send the command by reading from my read store to check if it is valid when creating a create post command or update post command.

I can think of two "solutions".

  1. Have a Blog aggregate that keep tracks of all blog related settings and also references to all the posts. But the problem with this in my eyes is that I have to handle communication between aggregates in that scenario as well as every time I need to validate the uniqueness of a shortUrl I need to read all the events from the event store to create all the posts and that seems to complicated.
  2. The second alternative I have is when the event gets fired and my event handler that creates the read model fires a duplicate short url event when it notice that it will have two short urls that points to different posts. Is it valid to have the read model to fire events when it detects errors?

Are there any more alternatives. Note that I know that my domain might not be the best fit for cqrs and DDD, but I'm doing this to learn in a small domain.

Best Answer

I would go for an application service that is just responsible for generating unique ShortURL's. You can use a transactional DB to implement this behaviour. Typically this service would be used by the command handling part of the BlogPost aggregate. If there is a duplicate ShortURL, you can fire a DuplicateUrlErrorEvent. You can pre-catch this in the UI (but never 100%) by creating a thin query-model using the same data-source, so you can query whether a shortified URL is unique before submitting the post (as described by @RyanR's answer).

Related Topic