Transitioning to Polylith

Last updated 18 days ago

How much will Polylith affect our current deployment setup?

Migrating to Polylith from a Monolith, Microservices or Serverless architecture is relatively easy. That's because we can individually migrate each artefact to a Polylith system without changing anything else about our deployment.

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 system.

Let's take a look at the steps involved in transitioning from each type of architecture.

From a Monolith

Don't forget to check that the system compiles, builds and all tests pass after each step.

1. Create a new workspace, and add a new system, with an empty base. 2. Copy all your Monolith's code, including its API and libraries, into the base.

Now we have a system with a huge "monolithic" base and a bunch of libraries

3. Extract all the code from the base (except the API) into a single "monolithic" component:

Now we have a system with a thin base and a huge "monolithic" component

It's tempting to do a lot of refactoring during this first component extraction phase, but we'd advise against that. Instead, we should just move all our code into a single component, and change as little as possible about its structure. This ensures that we don't introduce any bugs, and gives us a known and stable state to continue from.

4. This is where the real fun starts, because now we can refactor the code to increase the quality of the system. We start by teasing out one component at a time from our "monolithic" component:

Now we have a system with five components

When we've finished extracting all the components, we'll have a system that's in good 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.

From Microservices

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:

It's tempting to try merging components across system boundaries as soon as we notice similarities. We'd advise against this because during the transition we want every Polylith Microservice to behave exactly the same as before. This ensures that we don't introduce any bugs and gives us a known and stable state to continue from.

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 systems. 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 systems than we actually need to achieve the scalability we require.

Those additional systems come with a hefty complexity cost, so we'll be able to make our life much simpler by combining them into fewer Polylith systems. Whilst still maintaining the architectural benefits of separating our code into single responsibility components.

From Serverless

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:

A Lambda function with a single endpoint (the "handler function")

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.