One approach that works very well with transaction based interactions (like order management, supply chain management, stock trading, etc) is Event Sourcing. With an Event Sourced architecture, your event stream is your model. You then can project that stream of events into the forms that better meet your query and display needs.
In this approach, every order will have its own Event Stream (list of events from the beginning of the order to its completion).
This architecture works well with Command Query Responsibility Separation (CQRS) where Commands perform all the validations and preparatory work needed for your business process, but the end result is appending a message to the Event Stream for your Order.
Naturally, the concept of an Event Store has come up to derive the need of persistence. The Event Store will store the chronological stream of events for each Event Stream so they can be replayed.
If you combine the two you have a very powerful architecture. You can have separate microservices for the business logic side of things and the display side of things. The business logic is done in Commands, and writes events to the appropriate Event Stream into the Event Store. The view side of things reads from the Event Store the events not processed in the Event Stream, and Projects it into a database (RDBMS, graph, document, search) that is better suited for querying. That allows you to scale the writes and views separately if that’s needed.
If necessary, you can build new Command microservices for each of the new responsibilities. Those commands perform the validations and additional logic needed to make sure the process is done correctly, and the end result is an Event in the EventStream to record that the work has been done.
Critical aspects of Event Sourcing:
- Events are in Past Tense, indicating work that has already been completed
- Projections (in functional languages, a left fold) transform the Event Stream for display or query purposes
- The Event Stream is your authoritative state
Distinction between Event Sourcing and Event Driving:
- Event Driven architecture has events in Present Tense, and reflect commands that will be handled by another service
- Event Sourced architecture has events in Past Tense, reflecting that the work has already been done (AKA facts)
- Event Sourcing does not require sending events over a queue, a similar effect can be had by having other services query a shared event store
- Work can be distributed among many microservices that handle one function, allowing you to distribute logic appropriately
- The Event Stream doubles as an authoritative audit log
- Event Versioning is something that you have to consider carefully
- There can be conflicting events, requiring human review–particularly in a distributed environment
NOTE: CQRS is not necessary with Event Sourcing, but it fits naturally and works well with it. Many examples you find with Event Sourcing is coupled with CQRS.