Handling data dependent validation

46 views
Skip to first unread message

Chris Nicola

unread,
Jan 11, 2011, 3:35:09 PM1/11/11
to DDD/CQRS
So I'm curious what is the right way to approach this problem. Lets
say I have a product catalog where products can a Type and can have
one or many Categories. However types and categories are managed
outside of adding new products.

When a user adds or updates a product we want to make sure the type
and categories for that product are valid. Where should we check
this? Is this part of command validation. Obviously the list of
types and categories are not part of the state of a Product itself,
but is part of some external state, which we will have to query from
somewhere.

So my assumption is that when a command comes in the command handler
queries read model data for the list of categories and types and then
uses that data to validate my command. Is this correct?

@seagile

unread,
Jan 11, 2011, 3:51:19 PM1/11/11
to DDD/CQRS
- Are these types and categories aggregates as well?
- Is there behavior with regard to assigning a product to one or more
categories?
- Can a product change type over the course of its life?

I usually load up the aggregates and have them collaborate to
establish/dissolve a relationship.

ICommandHandler<AddProductToCategoryCommand> {
void Handle(AddProductToCategoryCommand command) {
ProductCategory productCategory;
if(!
_productCategoryRepository.TryGetById(command.ProductCategoryRef.Id,
out productCategory)) {
throw new
CommandHandlerException<AddProductToCategoryErrorCode>(AddProductToCategoryErrorCode.ProductCategoryUnknown);
}
Product product;
if(!_productRepository.TryGetById(command.ProductRef.Id, out
product)) {
throw new
CommandHandlerException<AddProductToCategoryErrorCode>(AddProductToCategoryErrorCode.ProductTypeUnknown);
}
product.AddToCategory(productCategory);

@seagile

unread,
Jan 11, 2011, 3:59:39 PM1/11/11
to DDD/CQRS
Just to clarify, if it's (types/categories) really external to the
system, I'd put that behind an abstraction and have a dedicated
validation component that has an implementation of that abstraction.
Pretty much as you suggested.

Another approach I have used is generating a token that proves that
the data in the command is valid and not tempered with and embed the
token in the command so the server can verify it's validity. This way
the server is not bothered with the validation (at least without the
need for querying the read model over and over again).

Nuno Lopes

unread,
Jan 11, 2011, 4:38:51 PM1/11/11
to ddd...@googlegroups.com
> When a user adds or updates a product we want to make sure the type
> and categories for that product are valid.

Can you give an example of what you mean by valid beyond that a given categories and type are defined (exists in the system)?

Sent from my iPad

Chris Nicola

unread,
Jan 11, 2011, 5:03:30 PM1/11/11
to DDD/CQRS
Sorry, we want to make sure the categories or features have already
been added to the category/feature collections and exist. A user
creating a product may not have permission to make changes to the
allowable features.,

On Jan 11, 1:38 pm, Nuno Lopes <nbplo...@gmail.com> wrote:
> > When a user adds or updates a product we want to make sure the type
> > and categories for that product are valid.
>
> Can you give an example of what you mean by valid beyond  that a given categories and type are defined (exists in the system)?
>
> Sent from my iPad
>

Nuno Lopes

unread,
Jan 11, 2011, 5:34:30 PM1/11/11
to ddd...@googlegroups.com
Considering your technical environment what is the validation problem having the user select a a category over a list of available categories for a given product?

Are you afraid the user might "inject" a category or a product type not available in the list presented to him?

Cheers,

Nuno

Chris Nicola

unread,
Jan 11, 2011, 6:06:01 PM1/11/11
to DDD/CQRS
That would put all the responsibility for validation on the client and
would require us to implicitly trust the client. Since the entire
thing is exposed via a REST API so we definitely wouldn't want to
always trust commands to be valid. I'm not sure if that would be good
in any environment though.

On Jan 11, 2:34 pm, Nuno Lopes <nbplo...@gmail.com> wrote:
> Considering your technical environment what is the validation problem having
> the user select a a category over a list of available categories for a given
> product?
>
> Are you afraid the user might "inject" a category or a product type not
> available in the list presented to him?
>
> Cheers,
>
> Nuno
>

Nuno Lopes

unread,
Jan 12, 2011, 4:14:58 AM1/12/11
to ddd...@googlegroups.com
From a data perspective this seams to be a problem of referential integrity. One of the things that I've seen being dropped several times due to performance.

From a interface perspective this seams to be a contract problem.

Either way if a non existent reference is given there will be an exception down the road granting the data to be invalid.

Assuming your clients are authenticated and the connection is secure I don't see much problems.

Now if the connection is open, the client is unidentifiable and acts maliciously you have other problems that by solving would help to solve this one.

This is like when making Order, should the system validate that the product reference is valid in the Product Catalogue (as existing) upon submitting it or let it flow? If we let it flow what is the worst it an happen? Order cancelled?

Sent from my iPad

Nuno Lopes

unread,
Jan 12, 2011, 4:50:26 AM1/12/11
to ddd...@googlegroups.com
As a note. I'm not insensitive to this problem.

A more intricate yet similar happened in a Client. I was asked to break the system.

I managed to make an Order for an existing product with a different price. The product in the catalogue was priced $500 and I made the order with a price of $5. This because the system was accepting the product price given by the Client rather then getting the price from the catalogue upon adding it to the order. When I mean client I mean the Web browser.

The problem was solved not by getting the price from the catalogue but by having the UI getting the price from the data stored in the user session cache in the server. Every data presented was stored in the user session you see.

You may think that was not a good choice but it solved the problem. You may think differently if I told you the price was a result of an intricate Insurance simulation that was yet to be recorded. So, no reference yet existed to the product selected product apart from it's type.

Sent from my iPad

Reply all
Reply to author
Forward
0 new messages