Application Architecture Styles Reference Models
Here is a summary of the different types of application architecture styles.
In software engineering, a monolithic application describes a single-tiered software application in which the user interface and data access code are combined into a single program from a single platform.
Monoliths have the following properties:
- Monoliths share a common codebase where all layers of an application exist in a single system.
- A single database where all transactions often take place.
- Tightly-coupled services where components depend on each other to function.
- A single codebase reduces the complexity of managing deployments.
- Cross-cutting concerns are often handled by the application. These include how modules are used across the organisation, and how security such as authentication and authorisation is handled.
- A lower total cost of ownership in the first year, since a single application is either be purchased as a COTS product or built in-house.
- A tightly coupled codebase makes development difficult.
- Regression testing is critical to ensure that all other modules work as expected.
- The cost of infrastructure is often very high. Some Monolithic applications often have a very old codebase which also means older technologies. To accommodate these systems in today’s cloud-based solutions, these systems need to be built in Virtual Machines sized accordingly.
- Application updates or upgrades often require the entire system to be updated.
- Low resiliency and high availability.
- Monoliths are often difficult to configure and customise without impacting other modules in the system. This forces some organisations to not want to customise any further, sticking to using Out-the-box features only.
- The total cost of ownership can increase if more is desired of the application.
This type of architecture is the easiest to design. There are various patterns that can be leveraged to mitigate any disadvantages. For instance:
- Structuring the codebase based on TDD or BDD methods.
- Ensure small changes are made only, regression test parallel modules. If large changes need to be made, ensure enough time has been planned for regression tests. A 1:2, or 1:3 ratio (Design and Build: Test) 5 days to design and build, 10/20 days to test) could be applied.
- Cloud providers like Azure provide technologies for load balancing and high-availability scenarios.
- If this is a LOB application, the Monolith should be part of any strategic roadmap. Will the organisation continue to use the application 3, 5 or 10 years from now, what if any, are migration or decommission plans?
A client might be a web browser accessing an application like Salesforce which is located on a Server.
Client-Server architectures fall into small domain architectures:
- Presentation Layer (Client layer). The purpose of this layer is to communicate with the application layer.
- Application Layer (Business Logic layer). The application layer is the application itself; it is a mediator between the Presentation ad the Data layer.
- Data Layer (Database layer). The application communicates with the data layer to perform the relevant CRUD operations.
The architecture can be further decomposed into Tiers:
1-Tier architecture (Standalone application)
The client contains the presentation, application and data layers, e.g. Microsoft Office.
2-Tier architecture (Client-Server application).
The Client has an application that communicates with a database that is online.
3-Tier architecture (web-based application)
The client communicates with the application which is hosted on a server. In turn, the application communicates with the database hosted on another server.
N-Tier architecture (Distributed application)
Similar to 3-Tier, the number of application servers has been increased to provide load balancing and high availability.
- Centralisation of control
- Greater security
- Dedicated Servers to manage incoming requests
- Maintenance is also often easier.
- Communication is point-to-point over HTTP or RPC.
- A single server means traffic needs to be routed correctly. Load Balancers should be used.
- Server redundancy, High-availability and resilience planning are critical to the success of a Client-Server architecture.
- A server will often contain a single database.
Simple 1-tier applications can be built relatively quickly using the following tools:
- Application using Node.js/Electron, Win32, WPF, Windows Forms, UWP, .NET MAUI and React Native for Windows.
- For 2-tier and higher applications, Microsoft Azure and Amazon AWS services provide toolsets for both containerised and standalone hosted applications.
Architectural style, not a technology or a pattern.
- Microservices architecture aims to create granularity between services. Services aim to have a single responsibility ultimately de-coupling services.
- A common design pattern in Microservices is to use an API Gateway between services; services never interact or share data through a point-to-point or RPC communication channel.
- Aims to reduce the data model to a similar granularity.
- To promote the concept of Bounded Context. Services are restricted to performing a single responsibility and nothing beyond that.
- Microservices follow a ‘shared-nothing’ approach. This means that each service is hosted in a separate computing platform, with its own database.
- Smaller codebase/services to manage.
- De-couples services.
- Can be created, destroyed, and replenished on demand.
- Services are containerised making it possible to move from one platform to another.
- Introduces complexity, especially in a Polyglot architecture.
- Can be difficult to debug if the end-to-end process is unknown. For example, if a customer’s payment fails, which service do you investigate, the CRM, Order module, Sales module, or the payment gateway? To mitigate risks a central logging framework should be included.
- Microservices are containerized.
- Services always communicate with other services through an API gateway.
- API gateways can be public, internal, or private/public Third-party.
- Because services are discreet, they can be hosted in containers that are appropriately scaled.
- Docker containers, Azure App Containers, Azure Container Services, and Kubernetes are options to build and deploy containers.
This is an architectural style, not a technology or a pattern. The Reactive Manifesto is a set of community-driven guidelines that aim to provide architects with a set of cohesive approaches when building event-driven architectures.
- Based on a Publisher/Subscriber model. Publishers send message events to a message broker like RabbitMQ or Azure Service Bus, these messages are consumed by a Receiver.
- Event-driven architectures are asynchronous events produced by an Emitter. These events are transferred as messages to an Event Channel. Event Sinks consume events.
- Event-driven architectures aim to de-couple services with the aim of services having a single responsibility.
- Provides Loose coupling.
- Provides fault tolerance and some degree of high availability.
- Cost-effective due to the work being distributed between the Event Producer and the Event Processor and Receiver.
- Provides a greater degree of flexibility. EDA can be combined with Microservices architecture.
- Asynchronous messaging can be combined with messaging systems that provide Guaranteed Delivery.
- A high degree of maintenance.
- Messaging systems introduce consistency issues.
- Exception handling is very complex (see Guaranteed Delivery Message Channel Enterprise Integration Pattern article).
- The nature of asynchronous messaging introduces duplicate messages, event sequencing and overall workflow control.
- Functional testing or end-to-end testing, and regression testing can become complicated.
In Microsoft Azure an Event-driven architecture can be created using the following technologies; Azure Service Bus and Azure Event Hub (both pull-based models), with Azure Event Grid (a push-based model). In none Azure ecosystems message systems like RabbitMQ, and Apache Kafka can be used.
Service-Oriente Architecture (SOA)
- Emphasis on Business Services over components.
- Aims to provide greater interoperability.
- Loosely coupled.
- Uses standard interfaces and protocols to communicate.
- Unbounded, services internal and external are connected through standard interfaces.
- Maximises service reusability.
- Uses an ESB to communicate between services.
- Shares the same data storage.
- Loose coupling provides platform independence.
- Is extensible and scalable.
- Introduces complexity in the overall architecture.
- Costs can grow as more services are leveraged.
- Higher network bandwidth since services are communicating over the wire with other services.
- Older applications using SOA have a tendency to leverage older message formats and technologies.
- The services are often designed and built in a complex fashion; e.g a service that provides payment functionality only may end up providing a complete CRM solution that needs to be incorporated into the end-to-end design.
Service-Oriented Architectures are less prevalent with cloud-based technologies. The architecture style ‘Microservices’ was based on the concept of SOA.
SOA can still be designed using WCF (Windows Communication Foundation). Many of Microsoft’s distributed technologies are based on WCF. For example, Microsoft Dynamics and Microsoft Azure.
It is no longer recommended that WCF is used to build SOA applications.
Hub & Spoke Architecture
In a Hub & Spoke architecture, applications connect to a central Hub. Messages or data can be passed back and forth between the Hub and the Spokes. This architecture is common in data warehouse architectures.
- The Hub & Spoke architecture is relatively simple to design and build compared to other systems architectures.
- The Hub is responsible for data transformation, data quality, message routing and applying other data rules.
- The centralised nature of the Hub & Spoke model makes governing data easier.
- Systems connecting to the Hub have lightweight endpoints; the sole responsibility is to send messages/data to the Hub.
- The state is maintained in a shared database.
- Can be scaled easily vertically if required.
- The centralised nature of the Hub & Spoke means that the single point of failure is the Hub. If the Hub fails, the complete system fails.
- Horizontal scalability & performance issues are common with a Hub & Spoke architecture.
- Can become difficult to manage over time with more spokes being added.
- Inter-dependencies between systems may cause the Hub to fail. For example, if System A sends Customer data to the Hub and System B sends incomplete Order information to the Hub, System C may fail or halt because the Hub is unable to send complete Customer data.
- Chatty-IO issues between a Spoke and Hub may cause performance issues for the other Spokes.
Hub & Spoke architectures are generally technology-specific. For complex scenarios, alternative data store models such as NoSQL (Table/Document) exist which alleviates some scaling issues.