The techniques involved in creating modern web applications are continually evolving. It can be difficult to separate out the ones that are truly improving how web applications are developed from those experiments that, while often interesting, are ultimately not worth investing in. From this sea of ideas a couple of trends have risen to the top and are radically changing how web applications are developed. These techniques are microservice-based architectures on the server and single page applications (SPAs) on the client. While an initial review of these two techniques doesn’t reveal any relation, a deeper analysis shows that these two trends are actually great partners and can be combined to enable powerful, yet maintainable, applications to be created.
When web applications were first being created, they tended to consist of a combination of server-side scripts, HTML markup, and styling information in a single file. Over time, the need to separate concerns lead to the wide use of the Model-View-Controller (MVC) design pattern to improve the organization of the application, simplify its creation, and increase maintainability.
The MVC pattern provided a huge improvement and became the mainstay of server-side software development patterns for many years. However, very large applications still struggled with staying organized due to the large number of resources and business rules that they had to manage. This was caused by the fact that each application was trying to be responsible for every aspect of the business problem that was being solved. As an example, a personnel management system is typically responsible for individual employee records, benefits and payment information, training records, and so on. From the users’ perspectives, this makes sense since it allows them to manage every aspect of an employee’s records from a single application. However, the underlying complexity of the application can lead to the system becoming unmanageable over time.
Microservices are a technique that promise to reduce the burden that the server is carrying while providing the array of services associated with large business applications. This is accomplished by separating the server’s data and business logic into smaller web services that are then combined to deliver the required features to the user. This has the effect of trading application complexity for system complexity. A microservice-based architecture is more difficult to design and maintain at a system level, but each individual component of the system a greatly simplified. When the proper balance is struck between the number and complexity of each service, the overall system can become much simpler to work with. In the previous example, an employee service that uses microservices might have one service that exposes core employee data (hire date, personal information, etc), another that contains training records, and yet another that contains information about benefits. By combining these smaller, more focused services together, the business application can expose the same features as the previous monolithic example. However, the application only has to combine the services that are provided to it rather than implementing all of the the rules within itself. This greatly reduces its responsibilities and, as a side benefit, allows the services to be used by other applications as well.
Single Page Applications
Returning to the dawn of web applications, the server was responsible for rendering all of the content for a screen. When the user entered some data, or navigated to a new screen, a new request would be sent to the server which would respond with the new page as required. While this worked well, the constant page refreshing could be disruptive to the user and made web applications feel sluggish compared to desktop solutions that were addressing similar problems. With the rise of asynchronous communication with the server via Ajax, it became possible to introduce new content on demand without a full-page refresh and allowed web applications to approach the responsiveness and feature set that desktop applications enjoyed for years. Many libraries, including the Dojo Toolkit, have built this capability and provide additional tooling to simplify web application development.
So microservices were designed to reduce server-side application complexity and single page applications serve to improve the user experience. So how can they be related to reduce complexity?
One of the side effects of how a single page application works is that it tends to change the type of information that the client-side application is seeking. Older style client-side applications would send data back to the server and expect pre-processed HTML back. Single page applications, however, tend to send and receive pure data streams. The SPA will then interpret the response and create the appropriate presentation of that data to the user. This change removes the requirement from the server to provide the context for the data, making it more portable and reusable. Extending this reasoning further, it becomes much simpler for a SPA to consume data from multiple sources without those sources knowing how the data will be used and, thus, makes them prime candidates for consuming microservices directly. This is especially true in enterprise environments where cross-application resource sharing (aka CORS) enables a SPA to use data from microservices that are hosted in different domains. This allows an application’s server-side to become even simpler: it simply delivers the assets that the SPA requires and it gathers the data that it needs independently.
While modern web applications continue to become more complex and are forced to meet ever increasing expectations of performance and quality, there are some powerful techniques that promise to enable engineers to meet these challenges. By using microservices to balance the complexity of a system’s architecture with that of each individual service, server-side engineers have a much better chance at building a stable, well-tested, and scalable backend. Meanwhile, single page applications allow sophisticated applications to be created that are both feature-rich and responsive. Additionally, further benefits can be realized by combining these two strategies and using the data-centric nature of SPAs to tap directly into multiple microservices that contain the data and logic that are required to meet users’ demands.