A single micro-service within a web-application typically has multiple different states that it has to manage, with certain scenarios involving fairly complex transforms.
The lure of the state machine
Let’s take an e-commerce application. An order can contain multiple products, each of which could be fulfilled individually. If the e-commerce application supports bulk ordering, it is even possible that even within one product, fulfilment could be done through multiple vendors. Add to it cancellations, returns, failed orders, and stuck payments, and it leads to a fairly complex set of states. This makes it alluring to have a state machine, with states and substates and state changes triggered by certain actions.
Where are state machines useful
There are some aspects of web applications that make it useful to have a state machine. For example, gaming applications and user interfaces often benefit from having state machines. There is a clear mapping between the state and how it should appear on screen. Every action can trigger a state change, and every state change can trigger another action. In computer games, every object could possibly modelled as an individual state machine.
The downside of state machines
In this respect, backend applications are a little different from games. In games, state machines flow beautifully. A state change triggers an event, a subscriber responds to the event, which could possibly trigger another state change. The states and logic are complex but contained. In backend applications on the other hand, the real complexity is in the interactions with other systems. One system could be dealing with multiple different domains in just one webservice. The system has states and substates, with each interaction triggering an action that could be very different from another action. One service could be calling a third party service, writing to a database, and sending a kafka event, whereas another service could be doing something totally different. This makes the state machine large, and convoluted.
Alternatives to state machines
In web applications, an alternative to having a state machine is to have something slightly different. To take the e-commerce example, the state of every order and the individual fulfilment within that order could be stored in the database. But it is not necessary to manage all of that through a central state machine. Each service interacting with a particular domain would need to understand how a particular action affects the state in the database and vice versa. This leads to a situation where the state is centralised, but the logic is distributed.
Having specific state machines
Incase one needs a state machine on the backend, it should be specific and contained, not a God object managing every interaction. It can be related to a specific component or a domain. This allows specific components to utilise their own state machines, but avoid the trap of having all the application logic flowing through a single state machine.