We're starting to work on microservices to rebuild our legacy application, piece by piece. We started by building a register module which is responsible for the whole register process.
To simplify, let's say the RegisterModule
will use a CustomerModule
to persist a customer, and then a PhoneModule
that needs a customer_id
to persist a phone in the database.
CustomerModule
would look like this in pseudocode :
<?php
class CustomerModule
{
public function createCustomer(array $inputs)
{
$this->checkInputs($inputs);
$customer = $this->repository->create($inputs);
$this->phoneModule->createPhone($customer->getId(), $inputs);
return json_encode(['data' => '1']);
}
}
checkInputs
would throw an exception handled by the upper layers in the module which would return the errors to the RegisterModule
with the right HTTP code. Nothing persisted, data is consistent.
Now with the PhoneModule
pseudocode :
<?php
class PhoneModule
{
public function createPhone(integer $customerId, array $inputs)
{
$this->checkInputs($inputs);
$phone = $this->repository->create($customerId, $inputs);
return json_encode(['data' => '1']);
}
}
Again, when checkInputs
encounters a validation error, nothing will be persisted for that microservice. But the problem here is that the CustomerModule
has already persisted a customer in its database. But this customer has no phone associated which is not what we want.
I have read a lot about distributed transactions. My CTO does not want to hear about eventual consistency (and in this case I'm 100% on his side). Most solutions I have seen look very hard to implement, and I'm not even sure those are the tools we need to solve this problem.
A solution could be to do all the checking beforehand, and then do the persisting actions. But that either would mean duplication of checking in both the persisting and the checking routes, or that mean we could persist without any check if we "forget" to do the checks beforehand.
How do you handle this in the most simple way ?