Let's say that we have twelve Microservices in our current solution. After we complete the initial stage of a migration to Polylith, then we'll still have twelve Microservices, but each will be a Polylith service.
Let's take a look at the steps involved in transitioning from each type of architecture.
1. Create a new workspace, and add a new service, with an empty base. 2. Copy all your Monolith's code, including its API and libraries, into the base.
3. Extract all the code from the base (except the API) into a single "monolithic" component:
4. This is where the real fun starts, because now we can refactor the code to increase the modularity of the service. We start by teasing out one component at a time from our "monolithic" component:
When we've finished extracting all the components, we'll have a service that's in much better shape. Some components will handle a specific part of our domain, some might manage integration with external systems, and others will be responsible for infrastructure features such as logging or persistence.
Microservices is an architecture consisting of many small Monoliths. This means that migrating to Polylith is as simple as performing the Monolith migration steps on each service:
Once the initial migration of all our microservices to Polyliths is complete, then we can start to refactor.
It's likely that there are a number of common components that can be shared across mulitple services. Resuing components in this way, make our codebase DRY and easier to maintain.
We might also discover that we had prematurely optimised our Microservice architecture for scalability and/or single responsibility. In other words, we have more services than we actually need to achieve the scalability we require.
Those additional services come with a hefty complexity cost, so we'll be able to make our life much simpler by combining them into fewer Polylith services. Whilst still maintaining the architectural benefits of separating our code into single responsibility components.
Serverless is an architecture consisting of many Lambda functions. This means that migrating to Polylith is as simple as performing the Monolith migration steps on each Lambda:
As with Microservices, we are not forced to migrate all our Lambdas at the same time. If we have many Lambdas this is especially good news, because it allows us to migrate in small and controlled steps.