When starting a new project, the architecture that you choose will have major implications on the quality, longevity, and performance of your application. Monolithic architectures have been the go-to for many applications up until recently. A monolithic application is an application that consists of the user layer (UI), data access layer (business logic), and the data store (database) that are all generally tightly coupled. While this monolithic approach is simple to develop, deploy, and scale at first, there are drawbacks as the application begins to grow.
Typically, as an application grows in complexity, so too does the size of the team. This can lead to inefficiencies in the Software Development Lifecycle (SDLC). As part of this team growth, onboarding new team members requires more time and effort as they need to understand all aspects of the application in order to support and modify it. Depending on the technology stack implemented, a larger, more complex application can lead to slower development due to overloaded IDEs, slower startup time, both in testing and deployment and generally a less productive development team overall. This approach also confines the project to using the same tech stack over a greater period.
A popular alternative in recent years has been the microservice architecture. This plan breaks down a single application into multiple services which are completely independent from one another, allowing teams to more easily manage them and improving maintainability. With this approach, each service can be managed by a smaller team. In certain cases, a team may manage more than one service, but rarely would one team manage all services for an application. The main benefit to this approach is that if a bug is discovered in one service, that bug is much less likely to impact the rest of the application. That failing service can be fixed and redeployed without any downtime to the remainder of the application.
Other important benefits include the ease of CI/CD integration with microservice based applications. Changes can be pushed out more frequently and with less risk due to the codebases being much smaller and very loosely coupled. Lastly, because you’ve separated your data access layer and data store, you can easily change components for your front end. Is there a new technology stack that makes your front end obsolete? No problem! You’ve abstracted your so changing the view of the application is very low risk and a change that can be done faster.
Admittedly when starting a new project, taking the time to plan out a complex distributed system can be both tedious and daunting. For larger companies who know their applications will need to be able to function on a large scale this level of planning is often worth it, but for smaller projects and independent developers this is not always the case. In these situations, it may be more beneficial to start with a monolithic architecture and then graduate to microservices in the future if there is the need to do so. A microservices approach can also lead to greater memory requirements, particularly if each service requires its own JVM and/or Virtual machine. Again, this issue is primarily a concern for smaller teams which may not have the resources to support these system demands.
If you are working on a monolithic application and come to the decision that you need to migrate to a microservices architecture, there are a few ideas to keep in mind when splitting functionality into separate services.
- Separate out services based on business requirements.
- Define services by verb or use case. For example, a Shipping Service that is responsible for shipping complete orders.
- Define services by noun or resource. For example, a Book Service that is responsible for all operations on books or book data
The microservices architecture has been around for years, and while it has evolved during that time, the underlying concept remains the same and is still widely implemented. With a strong understanding of microservices architecture, developers can more effectively contribute to both project planning and improvement, particularly when scaling smaller applications and upgrading the project’s tech stack.