Search code examples
domain-driven-designcqrsevent-sourcingaxon

Use value object in command and event?


Can we use value object in command ?

Suppose I have a Shop (aggregate) in which there is one value object Address. In the value object constructor Address ,I was put the some validation logic for address. So if I am using that Address object in command (CreateShopCmd) , then it get validated at the making of command , but What I want or Read that validation should be present in command handler.

But problem is that , I have to put that validation again in command handler (Since validation is already present in it Address constructor) and if I am not putting that in command handler , then the validation will occur when I am making the Address object in event handler and assign to Shop aggregate(Which is incorrect)

So, please guide me.

Below are code example

   @Aggregate
   @AggregateRoot
   public class Shop {

   @AggregateIdentifier
   private ShopId shopId;
   private String shopName;
   private Address address;

   @CommandHandler
   public Shop(CreateShopCmd cmd){

     //Validation Logic here , if not using the Address in 
     // in cmd

         //Fire an event after validation
         ShopRegistredEvt shopRegistredEvt = new ShopRegistredEvt();
         AggregateLifecycle.apply(shopRegistredEvt);
     }

     @EventSourcingHandler
     public void on(ShopRegistredEvt evt) {

     this.shopName = evt.getShopName();

     //Validation happend here if not put in cmd at the time of making 
     //Address object - this is wrong
     this.address = new Address(evt.getCity(),evt.getCountry(),evt.getZipCode())

     }


   }

  public class CreateShopCmd{

    private String shopId;
    private String shopName;
    private String city;
    private String zipCode;
    private String country;

   }

 public ShopCreatedEvent{

    private String shopId;
    private String shopName;
    private String city;
    private String zipCode;
    private String country;

}

Solution

  • I wouldn't suggest using Value Objects in commands. Cause your commands are part of the application layer, but Value Objects are kept in Domain Layer. You can use your ValueObjects in DomainEvens though. Because if domain model changes, modification of your domain event wouln't be that painful, cause the modification is done in the same bounded context. You should never use ValueObjects in integration events though.