Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deal with external stateful webservices in DDD?

Scenario #1

  • Situation: I need to perform a business operation on some data that is in a webservice.
  • Solution: The repository uses the webservice as repository, building the aggregate with the webservice data, and saving the changes later on.
  • Doubt: Is this OK ?

Scenario #2

  • Situation: I need to perform a business operation on some data that is in my database, and such operation involves a webservice for calculating a value.
  • Solution: The webservice is abstracted as a domain service, so it is passed to the aggregate as parameter to perform the operation.
  • Doubt: Does this make sense? I would say that the webservice should be part of the repository, so data is persisted together.

Scenario #3

  • Situation: The business operation request/saves data from/to two different databases, one is accessed directly the other through a webservice.
  • Solution: Both, database connection and webservice, are in the repository, and they are saved together. The aggregate does not know about this split.

Scenario #4 (problems start...)

  • Situation: I need to perform a business operation with data in the database, that involves a webservice operation, which result is needed for the business operation itself.
  • Problems: The webservice is not transactional, neither is under my control, although it is idempotent. The call to the webservice depends on some data that the aggregate has to load, and the aggregate logic depends on the result code that the webservice returns (imagine an online payment).
  • Solution: The webservice is used as a domain service, if the request fails everything fails, and it is retried later on. If the database fails when saving, it is retried as well.

Scenario #n [many many variants of #4] ...

So I cannot make my mind around a clear criteria on how to use webservices in DDD when they make changes in their state.

Ideally, I would do the changes in my storage, and then having some kind of integration layer that replicates those changes in external databases or services, with events for example. However, most of times there is a read-after-write consistency requirement, where if you refresh after a operation returns, the right data is shown on screen (eg: the payment receipt that comes from the same webservice where the payment was done).

Another example: A screen allows to save the data about a book, however the book specifications is saved in a database, and the descriptions (in several languages) are saved in an external service. The operation has to be consistent, if a user click "Save" and refresh, the screen needs to show all together, cannot just show the specifications with old translations or not translations at all because they are being replicated to another database.

Which is a solid criteria to decide?

like image 762
Vlad Avatar asked Oct 28 '25 14:10

Vlad


1 Answers

The answer is to read Life Beyond Distributed Transactions.

The short form is that trying to reliably coordinate writes at different locations is expensive. In most cases it is better to admit in your design that you can't be in all places at once, and invest in your handling of the consequences of that fact.

like image 199
VoiceOfUnreason Avatar answered Oct 30 '25 06:10

VoiceOfUnreason