问题描述:

I have got a question related to CQRS in data centric processes. Let me explain it better.

Consider we have a SOAP/JSON/whatever service, which transfers some data to our system during an integration process. It is said that in CQRS every state change must be achieved by the means of commands (or events if Event Sourcing is used).

When it comes to our integrating process we have got a great deal of structured DATA instead of a set of commands/events and I am wondering how to actually process those data.

// Some Façade service

class SomeService

{

$_someService;

public function __construct(SomeService $someService)

{

$this->_someService = $someService;

}

// Magic function to make it all good and

public function process($dto)

{

// if I get it correctly here I need somehow

// convert incoming dto (xml/json/array/etc)

// to a set of commands, i. e

$this->someService->doSomeStuff($dto->someStuffData);

// SomeStuffChangedEvent raised here

$this->someService->doSomeMoreStuff($dtom->someMoreStuffData);

// SomeMoreStuffChangedEvent raised here

}

}

My question is whether my suggestion is suitable in the given case or there may be some better methods to do what I need. Thank you in advance.

网友答案:

Agreed, a service may have a different interface. If you create a rest-api to update employees, you may want to provide an UpdateEmployeeMessage which contains everything that can change. In a CRUD-kind of service, this message would probably mirror the database.

Inside of the service, you can split the message into commands:

public void Update(UpdateEmployeeMessage message)
{
    bus.Send(new UpdateName
    {
        EmployeeId = message.EmployeeId,
        First = message.FirstName,
        Last = message.LastName,
    });

    bus.Send(new UpdateAddress
    {
        EmployeeId = message.EmployeeId,
        Street = message.Street,
        ZipCode = message.ZipCode,
        City = message.City
    });

    bus.Send(new UpdateContactInfo
    {
        EmployeeId = message.EmployeeId,
        Phone = message.Phone,
        Email = message.Email
    }); 
}

Or you could call the aggregate directly:

public void Update(UpdateEmployeeMessage message)
{
    var employee = repository.Get<Employee>(message.EmployeeId);

    employee.UpdateName(message.FirstName, message.LastName);
    employee.UpdateAddress(message.Street, message.ZipCode, message.City);
    employee.UpdatePhone(message.Phone);
    employee.UpdateEmail(message.Email);

    repository.Save(employee);
}
相关阅读:
Top