Where to put outside-aggregate validation?

163 views
Skip to first unread message

telemetrik

unread,
Jun 29, 2017, 11:40:08 AM6/29/17
to DDD/CQRS

Hey gang!


I've got a question regarding outside-aggregate validation.


In our domain partner can place orders that contain certain products (1). 

Once order is placed (2) he can mark it as paid (3) in our system.

Once order is marked as paid (4) we assign licences to products in external library service (5).

Once we know licences are assigned (6) we close entire saga.


Here's a small drawing illustrating the process:




At this moment besides commands, command handlers and events there are two domain classes that are involved in entire process: 

  • Order aggregate containing business logic
  • Order saga coordinating entire process and assigning licences


Now, there is one invariant that is not modelled in this process yet - before we mark order as paid we have to check if user does not already have particular licence assigned. We get this from library service as well. 


Where would you put this validation? Command handler? Wrap Order in some domain service? Pass some validator to Order constructor?


<?php

class Order
{
    public function __construct(OrderValidator $validator)
    {
        if (!$validator->isValid($this)) {
            throw new \DomainException();
        }
        
        // else proceed
    }
}

class OrderValidator
{
    private $libraryServiceClient;
    
    public function isValid(Order $order)
    {
        // check licence using $libraryServiceClient
    }
}




Danil Suits

unread,
Jul 3, 2017, 7:31:26 AM7/3/17
to DDD/CQRS

I would expect that to have a Task to check the result in the third party system (independent of the other tasks), which interacts with the third party system and publishes a domain event with the answer.  That event in turn gets routed to the process manager, which is responsible for figuring out how to coordinate that answer with the other activity in this protocol.

I don't see anything conceptually wrong with putting this into a domain service, but I think that implies a synchronous dependency on the library service.

Reply all
Reply to author
Forward
0 new messages