A frequent decision with new applications is adopting a monolithic vs. microservices architecture. While the concept of simplicity is core to microservices, coordinating interoperability between them is not simple. Boundaries between modules are not always clear in the beginning.
Abstracting logic from multiple microservices can be cumbersome when you need to revise those boundaries. Inter-process communication across a network also naturally increases points of failure, which translates to debugging infrastructure not code. That last part is key. Developer productivity suffers when the team is pulled away from focusing on core business logic. Core business logic is the reason we’re here in the first place.
When to Choose a Monolithic or Microservices Architecture
My advice for teams building new apps is to simplify your development workflow to maximize productivity. Building an application monolith can be a great strategy in this regard. Dependencies are self-contained, and you're deploying a single payload within each development cycle rather than orchestrating a web of interconnected deployments.
Refactoring can be swift especially when using an opinionated framework. Large distributed teams can also work on separate libraries within the monolith thereby closely approximating parallel development workflows. It all translates to fewer ancillary tasks distracting developers. Your team channels its brain power toward delivering business value and iterating quickly.
Separating out microservices from your monolith should remain a future priority, however. Triggered early on or years later, the imperatives for new microservices become clearer as the application evolves. Start out prepared to wait for boundaries between application concerns to stabilize even if it takes a while. But don’t be surprised when parts suddenly need to scale differently from the rest of the app necessitating short-term redress.
Likewise, evolving requirements could also demand the introduction of a new technology (e.g. machine learning), which could put you on a path to building a new service as well. Above all, avoid solving problems you don’t yet have (and may never have) with preemptive microservices. The opportunity cost of your team’s time is expensive.
When Delaying Microservices Signals the Need for Software Intelligence
Waiting to justify microservices can often be a difficult ask. Developers know how challenging it can be to reverse engineer aging parts of an application. In particular, areas that the team hasn't touched in a while may seem off-limits especially if the author is gone. Teams will need to employ an architectural strategy to balance any loss of performance or stability as new layers are introduced.
This is where we should turn to Software Intelligence tools to aid our decisioning. Static code analysis tools solved this problem years ago. In a scan, they produce blueprints of your entire codebase. These detailed maps juxtapose current and future architectures. The tools even intercept commits that violate your new contract as your team progresses toward the new architecture.
In summary, a move to a microservices architecture is a goal that can be delayed for many development teams. Prioritize developer productivity before trying to solve technical problems you don't currently have. Monoliths can be a powerful stepping stone in this journey. Best of all, rest assured that tools like static code analysis will be there to guide your microservice abstractions when the time is appropriate.