Microservices is a way of separating a system into smaller autonomous parts.
This can be done in many ways, but I’m most into the event-driven architecture and think that is at least a good start.
Every system I’ve been working with has started as a monolith. Some of them written in old languages like Cobol or Delphi, but some of them also in C#. What in a business that drives rewrite of a system is a separate discussion, but if these systems had been modularised in any way, it would have been so much easier (and cheaper) to step-by-step modernize them.
To be able to deal with technology changes of a system is a good reason to use a microservice architecture. To be able to rewrite business logic without affecting the whole system is another.
The possibility to deploy each service separately, has not made sense practically to me yet. Of course it depends on what type of system you’re working with. I think that to make sure that the services communicate using events (e.g. with pub-sub) and have separate data sources is much more important. This makes it easier to split the system if or when it is needed.
In an event-driven architecture, business events are identified e.g. using event storming. A business event can be something like when a booking is done or cancelled, or a hotel is available for booking. When a business event is published other subscribing services are triggered and performing their tasks.
The publishing service don’t know anything more than that e.g. a booking is done. And the subscribing service, let’s say an accounting service, has no idea of how a booking is made, only that it is done and it is time to perform the accounting tasks that it is responsible for.
An event-driven system is loosely coupled and asynchronous. The different services does not now anything about each others, and have no dependencies. In this way logic is isolated and has clear responsibilities. They can easily be deployed and scaled separately.
CQRS and Event sourcing
CQRS and event sourcing are ways of taking event-driven design further and think of, and store, every performed task in the system as an event. All except the read of the CRUD operations are saved as created, updated and deleted events. Of course business events are saved as events as well. You get the traceability of everything that has happened in the system. You also get the possibility to generate and regenerate read data in different forms depending on what’s needed.
Microservices is the way forward
Microservices tend to decrease complexity in systems when performing changes in each service. When you look at the whole, though, it might increase complexity. Especially if you’re going to deploy them separately. The infrastructure gets more complex and, for example, if you have different languages in the services, the developers need a broad range of skills.
I suggest that you try to think in generations if you have services in different technologies. Try to keep the number of different technologies down. Develop one bunch of services that are very similar to each other when it comes to structure and technology. When that technology is getting less popular or starts to feel outdated, begin a new generation of services with a new set of technology choices and continue with these for the next period of time. Maybe rewrite some of the old ones, if needed. And continue like this over the years.
From my perspective, microservices (either compiled together or completely separated) is the only way of making a system survive over time. Even the most modern, high tech technology eventually gets old-fashioned. If we don’t want to completely rewrite the whole system every 20th year, we have to split them into smaller units.
One benefit of continuously rewrite the parts of a system instead of rewrite it all at once is that it is easier to attract developers who tends to choose jobs where they get the possibility to work with new technology. I’m sure it is easier to find a python developer rather than a COBOL developer today, for example.
Want to read more? Start here.