Basically, an user wants to change its profile picture.
The web server receives a posted image against /user/35435/profile/picture
, so the data needs to be saved, and the LastModification
property of the profile object updated.
Images are not stored locally in the web server, they need to be uploaded somewhere else (ie: cloud storage).
At the moment, every operation is represented by either a Command or a Query. Commands run in an ambient transaction (like a SQL transaction). The image upload operation is not transactional, but a compensating action can be done in case of error (ie: removing the image if the DB operation fails).
On a naive implementation, a command containing both current date and the image data is created. A command handler is executed, it loads the ProfileAggregate
aggregate, and ProfileAggregate.updateProfilePicture(imageUploader, image, currentDate)
is executed passing the imageUploader
domain service as parameter. Inside the method, the image is uploaded and the profile updated. The command handler saves changes in the DB and returns.
I do not like the fact that a transaction is held during the image upload. I do not like either doing non-domain-model operations (like uploading the image) from within an aggregate (even if the aggregate is calling somewhere else).
Should this interaction modeled like two independent commands that are executed in serial fashion, or it is OK to put anything inside an aggregate as long there is no dependencies in concrete implementations.