Richard Wallace | 1 Sep 05:03
Picon
Gravatar

Re: Propagating messages and errors to the user interface

On Mon, Aug 31, 2009 at 10:07 AM, Richard Wallace<rwallace1979 <at> gmail.com> wrote:
> On Mon, Aug 31, 2009 at 12:21 AM, Udi
> Dahan<thesoftwaresimplist <at> gmail.com> wrote:
>>
>>
>> When doing REST, consider using the PRG pattern - POST (or PUT), Redirect,
>> GET.
>>
>> That way, you don't get tied to the original connection when returning a
>> response.
>>
>
> So, basically use a bunch of 202s?  And then have the client poll the
> server with GETs to figure out when the operation is complete?  I do
> take this approach for processes that I expect to be long running, but
> seems a bit silly to apply it to ALL scenarios.  Especially if the
> system isn't under too high a load and can handle the request in a
> timely manner.
>
> Rich
>

Also, if you take this approach don't you still need to listen for a
response to the message that is sent to the domain?  You need some way
to identify that the message executed either successfully or
unsuccessfully, probably by a message id.  Right?

>>
>>
>> Hope that helps.
(Continue reading)

Adam Dymitruk | 1 Sep 05:18
Gravatar

Re: Propagating messages and errors to the user interface

You would keep the correlation ID the same. The message ID would be a
new one for the "response" message.

On Mon, Aug 31, 2009 at 8:03 PM, Richard Wallace<rwallace1979 <at> gmail.com> wrote:
>
>
> On Mon, Aug 31, 2009 at 10:07 AM, Richard Wallace<rwallace1979 <at> gmail.com>
> wrote:
>> On Mon, Aug 31, 2009 at 12:21 AM, Udi
>> Dahan<thesoftwaresimplist <at> gmail.com> wrote:
>>>
>>>
>>> When doing REST, consider using the PRG pattern - POST (or PUT),
>>> Redirect,
>>> GET.
>>>
>>> That way, you don't get tied to the original connection when returning a
>>> response.
>>>
>>
>> So, basically use a bunch of 202s?  And then have the client poll the
>> server with GETs to figure out when the operation is complete?  I do
>> take this approach for processes that I expect to be long running, but
>> seems a bit silly to apply it to ALL scenarios.  Especially if the
>> system isn't under too high a load and can handle the request in a
>> timely manner.
>>
>> Rich
>>
>
(Continue reading)

bodrin | 1 Sep 09:40
Picon

Re: Validation context?



You then can instead say:
"Your purchase request is accepted. Please wait until it is approved."

From your requirements it seems that the domain should talk to this validation context
synchronously which means it should participate into the domain transaction?
So is it really a separate BC?
It seems to me more as a helper infrastructure like indexes and locks that can help
your applicaiton logic/domain to stay always in a valid system state.

On Mon, Aug 31, 2009 at 8:01 PM, Richard Wallace <rwallace1979 <at> gmail.com> wrote:
 

On Mon, Aug 31, 2009 at 3:16 AM, Udi Dahan<thesoftwaresimplist <at> gmail.com> wrote:
>
>
> Richard,
>
>
>
> I think you're taking validation one step too far.
>
>
>
> Validation states is the command worth considering - not that we're actually
> going to perform it.
>
> Business rules take a valid command and decide whether or not to actually do
> what it asks.
>
>
>
> At that level, validation is mostly string lengths, number and date ranges,
> things like that.
>
> No need for a separate bounded context for that.
>
>
>
> Hope that makes sense.
>

For that sort of low-level validation I understand that. But what
about the case of guaranteeing that all user names are unique? Or the
more complicated task of making sure that a user can only purchase
n-number of items - for instance, say you have a limited supply of
product and you don't want a single user to buy it all out, you want
to make sure other people get a chance to purchase. This is more at
the application level, inside a single aggregate root. How do you
handle that kind of validation? Compensating actions don't work
because you can't tell the user, "You're purchase was successful" one
second and then turn around and say, "Sorry, we decided not to sell
you anymore of that."

Rich


>
>
> -- Udi Dahan
>
>
>
> From: domaindrivendesign <at> yahoogroups.com
> [mailto:domaindrivendesign <at> yahoogroups.com] On Behalf Of Richard Wallace
> Sent: Monday, August 31, 2009 8:38 AM
> To: domaindrivendesign <at> yahoogroups.com
> Subject: [domaindrivendesign] Validation context?
>
>
>
>
>
> One of the things that I've been grappling with in trying to
> understand CQ(R)S is validation. Some systems will have fairly
> complex validation logic needs. There's been talk of using the
> reporting or other easily query-able context to fulfil these
> validation needs, but the problem is that reporting contexts are
> typically updated asynchronously. There are good reasons for them to
> be asynchronous, they might need to crunch some numbers or update
> denormalized data and that could take a while. But this conflicts
> with the needs of validation because we need to make sure that our
> system cannot entire into an invalid state. I've heard talk that the
> system can simply create events to fix itself, but it seems to me that
> we shouldn't let the system enter into an invalid state any more than
> we should let an aggregate root enter into an invalid state.
>
> So what I'm thinking might be a reasonable way to handle these
> conflicting needs is to split off a separate bounded context that
> purely deals with validation. This validation context could be
> updated synchronously with the domain so that it stays as up to date
> as possible. With the narrower focus of maintaining data purely for
> validation purposes, this should allow it to update much more rapidly
> than the reporting context. When you need to query about the validity
> of a command, you can simply send off an IsValid message that
> encapsulates the command to execute. Then the validation context
> could send a yes or no response - hopefully with additional details if
> the answer is no - and you'll know whether you can proceed to perform
> the action or not.
>
> This keeps the validation logic outside of the domain model but allows
> it to stay in sync with it, so that we can be sure we never go into an
> invalid system state.
>
> Is this similar to how other people are handling the problems related
> to doing complex validation in an asynchronous system or have you up
> with different ways? I'm eager to hear about other solutions!
>
> Thanks,
> Rich
>
>



__._,_.___


Your email settings: Individual Email|Traditional
Change settings via the Web (Yahoo! ID required)
Change settings via email: Switch delivery to Daily Digest | Switch to Fully Featured
Visit Your Group | Yahoo! Groups Terms of Use | Unsubscribe

__,_._,___
Nuno Lopes | 1 Sep 14:20
Picon
Gravatar

Re: Validation context?



Hi Richard,
 
"But what about the case of guaranteeing that all user names are unique?"
 
IMHO that i rule should be in the "Domain Layer" and not in the Application Layer,
 
Since the constraint is applied to the collection of all objects of a certain Class (sometimes referenced as the domain extent) I usually enforce these kind of rules at the Repository.
 
"Or the more complicated task of making sure that a user can only purchase
n-number of items - for instance, say you have a limited supply of
product and you don't want a single user to buy it all out, you want
to make sure other people get a chance to purchase."
 
Again IMHO that rule should be in the "Domain Layer" and not in the Application Layer.
 
First you would need to specify what is "limited supply". Anyway something like:
 
if (aOrderLine.OrderProduct.InLimitedSupply && aOrderLine.Qty > aProduct.LimitedSupplyPolicy.Qty))
    throw new BusinessEx("...");
}
...
 
This would probably be coded in the Class Order, Method AddOrderLine())
 
Something like that.
 
Cheers.
 
Nuno


__._,_.___

Your email settings: Individual Email|Traditional
Change settings via the Web (Yahoo! ID required)
Change settings via email: Switch delivery to Daily Digest | Switch to Fully Featured
Visit Your Group | Yahoo! Groups Terms of Use | Unsubscribe

__,_._,___
Richard Wallace | 1 Sep 16:48
Picon
Gravatar

Re: Validation context?

On Tue, Sep 1, 2009 at 5:20 AM, Nuno Lopes<nbplopes <at> gmail.com> wrote:
>
>
> Hi Richard,
>
> "But what about the case of guaranteeing that all user names are unique?"
>
> IMHO that i rule should be in the "Domain Layer" and not in the Application
> Layer,
>
> Since the constraint is applied to the collection of all objects of a
> certain Class (sometimes referenced as the domain extent) I usually enforce
> these kind of rules at the Repository.
>
> "Or the more complicated task of making sure that a user can only purchase
> n-number of items - for instance, say you have a limited supply of
> product and you don't want a single user to buy it all out, you want
> to make sure other people get a chance to purchase."
>
> Again IMHO that rule should be in the "Domain Layer" and not in the
> Application Layer.
>
> First you would need to specify what is "limited supply". Anyway something
> like:
>
> if (aOrderLine.OrderProduct.InLimitedSupply && aOrderLine.Qty >
> aProduct.LimitedSupplyPolicy.Qty))
> {
>     throw new BusinessEx("...");
> }
> ...
>
> This would probably be coded in the Class Order, Method AddOrderLine())
>
> Something like that.
>

I think you misunderstand.  If it was as simple as checking within a
single order that's no problem.  But we want to check against the
history of all orders for that product.  So let's refine the rule a
bit: Only 3 are allowed to be purchased per household.  If a person
comes in and orders 3 in one order, you don't want to allow them to
purchase any more.  But the logic still isn't as simple as just
checking that users past orders.  You need to check all orders and
compare the user that purchased, the shipping address and possibly the
credit card purchased with to be as sure as possible that you are
still being fair to all your customers.  So the validation can't take
place within a single entity, you have to be  able to query existing
orders to determine whether the new order is valid.

> Cheers.
>
> Nuno
>
> 

------------------------------------

Richard Wallace | 1 Sep 16:52
Picon
Gravatar

Re: Validation context?

On Tue, Sep 1, 2009 at 12:40 AM, bodrin<bodrin <at> gmail.com> wrote:
>
>
> You then can instead say:
> "Your purchase request is accepted. Please wait until it is approved."
>
> From your requirements it seems that the domain should talk to this
> validation context
> synchronously which means it should participate into the domain transaction?
> So is it really a separate BC?
> It seems to me more as a helper infrastructure like indexes and locks that
> can help
> your applicaiton logic/domain to stay always in a valid system state.
>

That's exactly what I'm looking for, and you're right it doesn't
belong in a separate bounded context.  Now that you put it that way,
it sounds like it would make far more sense to create a domain service
that handles abstracting the infrastructure bits out of the domain.
Make sense?

Thanks,
Rich

> On Mon, Aug 31, 2009 at 8:01 PM, Richard Wallace <rwallace1979 <at> gmail.com>
> wrote:
>>
>>
>>
>> On Mon, Aug 31, 2009 at 3:16 AM, Udi Dahan<thesoftwaresimplist <at> gmail.com>
>> wrote:
>> >
>> >
>> > Richard,
>> >
>> >
>> >
>> > I think you're taking validation one step too far.
>> >
>> >
>> >
>> > Validation states is the command worth considering - not that we're
>> > actually
>> > going to perform it.
>> >
>> > Business rules take a valid command and decide whether or not to
>> > actually do
>> > what it asks.
>> >
>> >
>> >
>> > At that level, validation is mostly string lengths, number and date
>> > ranges,
>> > things like that.
>> >
>> > No need for a separate bounded context for that.
>> >
>> >
>> >
>> > Hope that makes sense.
>> >
>>
>> For that sort of low-level validation I understand that. But what
>> about the case of guaranteeing that all user names are unique? Or the
>> more complicated task of making sure that a user can only purchase
>> n-number of items - for instance, say you have a limited supply of
>> product and you don't want a single user to buy it all out, you want
>> to make sure other people get a chance to purchase. This is more at
>> the application level, inside a single aggregate root. How do you
>> handle that kind of validation? Compensating actions don't work
>> because you can't tell the user, "You're purchase was successful" one
>> second and then turn around and say, "Sorry, we decided not to sell
>> you anymore of that."
>>
>> Rich
>>
>> >
>> >
>> > -- Udi Dahan
>> >
>> >
>> >
>> > From: domaindrivendesign <at> yahoogroups.com
>> > [mailto:domaindrivendesign <at> yahoogroups.com] On Behalf Of Richard Wallace
>> > Sent: Monday, August 31, 2009 8:38 AM
>> > To: domaindrivendesign <at> yahoogroups.com
>> > Subject: [domaindrivendesign] Validation context?
>> >
>> >
>> >
>> >
>> >
>> > One of the things that I've been grappling with in trying to
>> > understand CQ(R)S is validation. Some systems will have fairly
>> > complex validation logic needs. There's been talk of using the
>> > reporting or other easily query-able context to fulfil these
>> > validation needs, but the problem is that reporting contexts are
>> > typically updated asynchronously. There are good reasons for them to
>> > be asynchronous, they might need to crunch some numbers or update
>> > denormalized data and that could take a while. But this conflicts
>> > with the needs of validation because we need to make sure that our
>> > system cannot entire into an invalid state. I've heard talk that the
>> > system can simply create events to fix itself, but it seems to me that
>> > we shouldn't let the system enter into an invalid state any more than
>> > we should let an aggregate root enter into an invalid state.
>> >
>> > So what I'm thinking might be a reasonable way to handle these
>> > conflicting needs is to split off a separate bounded context that
>> > purely deals with validation. This validation context could be
>> > updated synchronously with the domain so that it stays as up to date
>> > as possible. With the narrower focus of maintaining data purely for
>> > validation purposes, this should allow it to update much more rapidly
>> > than the reporting context. When you need to query about the validity
>> > of a command, you can simply send off an IsValid message that
>> > encapsulates the command to execute. Then the validation context
>> > could send a yes or no response - hopefully with additional details if
>> > the answer is no - and you'll know whether you can proceed to perform
>> > the action or not.
>> >
>> > This keeps the validation logic outside of the domain model but allows
>> > it to stay in sync with it, so that we can be sure we never go into an
>> > invalid system state.
>> >
>> > Is this similar to how other people are handling the problems related
>> > to doing complex validation in an asynchronous system or have you up
>> > with different ways? I'm eager to hear about other solutions!
>> >
>> > Thanks,
>> > Rich
>> >
>> >
>
>
>
> 

------------------------------------

mrpmorris | 1 Sep 18:46
Picon
Gravatar

Re: References to composite parts

That makes sense, thanks.  I will allow references to composite parts :-)

------------------------------------

Nuno Lopes | 1 Sep 19:30
Picon
Gravatar

Re: Validation context?



In understand that the rule might be not that simple.
 
It seams that you need  to make the concept of OrdersPerHouseHold and HouseHold explicit in the model.
 
Nuno

On Tue, Sep 1, 2009 at 3:48 PM, Richard Wallace <rwallace1979 <at> gmail.com> wrote:
 

On Tue, Sep 1, 2009 at 5:20 AM, Nuno Lopes<nbplopes <at> gmail.com> wrote:
>
>
> Hi Richard,
>
> "But what about the case of guaranteeing that all user names are unique?"
>
> IMHO that i rule should be in the "Domain Layer" and not in the Application
> Layer,
>
> Since the constraint is applied to the collection of all objects of a
> certain Class (sometimes referenced as the domain extent) I usually enforce
> these kind of rules at the Repository.
>
> "Or the more complicated task of making sure that a user can only purchase
> n-number of items - for instance, say you have a limited supply of
> product and you don't want a single user to buy it all out, you want
> to make sure other people get a chance to purchase."
>
> Again IMHO that rule should be in the "Domain Layer" and not in the
> Application Layer.
>
> First you would need to specify what is "limited supply". Anyway something
> like:
>
> if (aOrderLine.OrderProduct.InLimitedSupply && aOrderLine.Qty >
> aProduct.LimitedSupplyPolicy.Qty))
> {
>     throw new BusinessEx("...");
> }
> ...
>
> This would probably be coded in the Class Order, Method AddOrderLine())
>
> Something like that.
>

I think you misunderstand. If it was as simple as checking within a
single order that's no problem. But we want to check against the
history of all orders for that product. So let's refine the rule a
bit: Only 3 are allowed to be purchased per household. If a person
comes in and orders 3 in one order, you don't want to allow them to
purchase any more. But the logic still isn't as simple as just
checking that users past orders. You need to check all orders and
compare the user that purchased, the shipping address and possibly the
credit card purchased with to be as sure as possible that you are
still being fair to all your customers. So the validation can't take
place within a single entity, you have to be able to query existing
orders to determine whether the new order is valid.

> Cheers.
>
> Nuno
>
>




__._,_.___


Your email settings: Individual Email|Traditional
Change settings via the Web (Yahoo! ID required)
Change settings via email: Switch delivery to Daily Digest | Switch to Fully Featured
Visit Your Group | Yahoo! Groups Terms of Use | Unsubscribe

__,_._,___
Greg Young | 1 Sep 21:01
Picon
Gravatar

Re: Re: References to composite parts

It would have to be globally readonly as it could be read in the
process of validating other items in the aggregate (think repeatable
read isolation level)

On Mon, Aug 31, 2009 at 12:32 PM, Alasdair Gilmour<alasdairg <at> gmail.com> wrote:
>
>
> As I understand it, the main reason nothing outside is allowed to reference
> the internals of an Aggregate is so that the Aggregate Root cannot be
> blind-sided by a client directly manipulating its composite parts without
> its knowledge, potentially violating constraints, invariants etc. However,
> if such a reference is strictly Read Only (as appears to be the case in your
> example where you are just saying "This property value corresponds to that
> Property"), then perhaps this restriction could be safely relaxed?
> For example, you could define an interface PropertyForReferenceOnly (no
> doubt a poor choice of name, but nothing else sprang to mind - you get the
> idea ...) which is implemented by Property, which just exposes its read-only
> attributes (e.g. name), and have your PropertyValues reference only
> PropertyForReferenceOnly interfaces. This would ensure that nobody could
> just navigate through a PropertyValue to a Property and change it in any
> way.
> Such usage seems like it would be very similar in nature to just holding a
> value object, which is "safe" and so could safely be allowed.
> Regards
> Alasdair
>> I think some elaboration is in order.
>>
>> A need to send data to a 3rd party. This 3rd party tells me they need the
>> following information.
>>
>> FirstName
>> LastName
>> NINumber
>>
>> So I record those as "properties" where the 3rdParty is the aggregate
>> root. All simple so far.
>>
>> Next I create a person and identify that they will be managed by a
>> particular 3rd party. I then have to enter values for those "properties". In
>> a DB I would typically link the
>> PropertyValue (of a person) to Property (of a 3rdParty).
>>
>> If the 3rdParty now says "Change NINumber to NationalInsuranceNumber" then
>> I need to be able to do that. Adding a non-business-meaning value to
>> "Property" is just the same
>> as giving it its own identity (like an aggregate root).
>>
>>To edit the 3rdParty's properties I will always use the 3rdParty to ensure
>> no conflicting updates to its property list, and ensure that there are no
>> duplicate property names for that
>> 3rdParty.
>>
>> So, should I only use 3rdParty+PropertyName when talking via the
>> Application Service, but within the DB store direct relationships, or what?
>> I am failing to see the advantage of
>> NOT having associations to composite parts of an aggregate root.
>>
>> Regards
>>
>> Pete
> 

--

-- 
Les erreurs de grammaire et de syntaxe ont été incluses pour m'assurer
de votre attention

------------------------------------

danh024680 | 1 Sep 21:30
Favicon

Re: Validation context?

--- Richard Wallace <rwallace1979@...> wrote:
>
> bodrin<bodrin@...> wrote:
> >
> > "Your purchase request is accepted. Please wait until it is approved."
> >
> 
> That's exactly what I'm looking for...

I think Bodrin's solution is good too, but note that all you're doing here is playing with ACID isolation
levels.  If you put a shared lock (isolation level 3) on the existing orders to prevent them being modified
under your feet then you wouldn't need to the accept/approved states in the PurchaseRequest domain
object.  If you go with anything lower than level 3 then you do need the compensate for the lack of isolation
in your domain (ie introduce two states).

It's the "eventually consistent" thing vs being consistent "right now".  Transaction volumes and whether
the object model naturally partitions itself should help determine which is most appropriate.

Dan
"Domain Driven Design using Naked Objects", pragprog.com

------------------------------------


Gmane