avatarAli Zeynalli

Summary

The provided web content outlines ten essential cloud-native architecture patterns that facilitate modularity, scalability, and maintainability in applications designed for dynamic cloud environments.

Abstract

The article discusses ten key architecture patterns tailored for cloud-native applications, which are typically composed of microservices. These patterns include Sidecar/Sidekick for service independence, Ambassador for enhancing legacy service connectivity, Scatter/Gather for aggregating responses from multiple services, Backends For Frontends (BFF) for creating an intermediary layer for frontend-backend communication, Anti-Corruption Layer for integrating services with different semantics, Command and Query Responsibility Segregation (CQRS) for separating read and write operations, Event Sourcing for maintaining a chronological log of data changes, Service Mesh for managing service-to-service communication, Dumb-Smart Components for separating presentation from data logic in frontends, and Unidirectional Architecture for streamlining data flow in reactive frontend frameworks. The patterns aim to address the unique challenges of cloud computing, such as separation of concerns and the need for dynamically orchestrated and containerized environments.

Opinions

  • The Sidecar/Sidekick pattern is deemed beneficial for abstracting peripheral application functionalities, such as logging and configuration, but may not be cost-effective if the resource overhead is too high.
  • The Ambassador pattern is considered useful for extending the capabilities of legacy services without modifying their codebase, though it introduces latency due to the proxy overhead.
  • The Scatter/Gather pattern is recognized as effective for controlling message flow and selecting the best response from multiple services, which is particularly useful for redundant legacy applications.
  • The BFF pattern is highlighted as a popular industry practice that facilitates orchestration between different frontends and backends, allowing for tailored responses and data model transformations.
  • The Anti-Corruption Layer pattern is seen as essential during the migration from legacy systems to new architectures, serving as a translator between different service semantics, despite adding complexity and latency.
  • CQRS is presented as a solution to the asymmetrical nature of complex database reads and writes, improving performance by separating these operations into distinct components, but it requires careful synchronization between read and write models.
  • Event Sourcing is praised for providing strong data consistency and a full audit trail by storing changes as a series of events, although it may be over-engineered for simple applications and is not ideal for real-time data-driven applications.
  • Service Mesh is recognized for its ability to isolate cross-cutting concerns from business logic, offering benefits like circuit breaking, rate limiting, and traffic management, which contribute to low latency and configurability.
  • The Dumb-Smart Components pattern is advocated for its clear separation of presentation and data flow, with Dumb Components handling display and Smart Components managing data interactions, which simplifies frontend development and testing.
  • Unidirectional Architecture is endorsed for its alignment with reactive programming principles, providing better control over data flow in modern frontend frameworks by using data streams.

The article concludes by inviting readers to explore additional cloud-native patterns and to connect with the author on social media platforms for further discussion on software engineering topics.

10 Must Know Cloud Native Architecture Patterns

Sidecar/Sidekick, Ambassador, Scatter/Gather, BFF, Anti-Corruption Layer, CQRS, Event Sourcing, Service Mesh, Dumb-Smart Components, Unidirectional Architecture

Photo by Alex wong on Unsplash

Software Architecting might take a slightly different approach in applications that are build in cloud-native environments. These applications are extensively built in forms of microservices. Beside that, these applications should be able to run in dynamically orchestrated and containerized environments in order to take advantage of cloud computing model.

Cloud native computing is an approach in software development that utilizes cloud computing to “build and run scalable applications in modern, dynamic environments such as public, private, and hybrid clouds”.

The motivation behind software architecture in cloud environment is separation of concerns, especially for modularizing software components in containers. Following patterns help to achieve this purpose.

1.Sidecar/Sidekick…

This pattern is helpful if you want to abstract away some peripheral part of your main application in different microservice. This aids to result in independence between services, breaking tightly coupled components.

Sidecar/Sidekick pattern is helpful choice if application uses a same languages and libraries and service is needed that shares the lifecycle but can be independently deployed. It would be bad decision to implement a Sidecar/Sidekick pattern to the application if resource cost of deploying sidecar service for each instance is not worth the advantage of isolation. The functionalities like logging, configuration etc. can be abstracted away to another microservice, as shown in example below. This pattern has 1:1 relation with Primary Service

Sidecar/Sidekick Pattern

2.Ambassador…

Ambassador pattern is often used to extend network abilities of existing service, especially for the cases that this service is old or complex enough to modify.

An ambassador service can be thought of as an out-of-process proxy that is co-located with the client.

Adding extra proxy through this pattern brings latency with itself. This pattern unlike Sidecar can be used for multiple services. This pattern can be helpful for enhancing connectivity functionalities of legacy services. This pattern is not a good choice if low latency is critical, since Ambassador pattern has a proxy overhead.

Ambassador Pattern

3.Scatter/Gather…

This pattern is used if legacy application is using redundant services. The main idea of this pattern is having a aggregator that summarises responses from different services and delivers the best quote. This pattern is is good to control the message flow to all miscroservices.

Scatter/Gather Pattern

4.Backends For Frontends…

The main gist of this pattern is making another layer of backend between frontends and real backends. This would be called Backend For Frontend. This is one the most popular patterns that is applied extensively in industry. By adding this kind of extra layer you can orchestrate between different frontend and backend servers, validate filter responses that come from frontend, map and convert the data models that are delivered from backend.

BFF Pattern

5.Anti-Corruption Layer…

This Pattern might be very helpful if you have different subsystems or microservices that don’t share same semantics. Anti-corruption Layer translates or integrates communication between those services. This pattern was first described by Eric Evans in Domain-Driven Design.

This kind of constellation can very well happen if you are in progress of migrating legacy system to new ones and party news systems use resources of functionalities of legacy systems.

Drawbacks and Side effects might be following:

  • this extra layer adds more latency
  • this layer is also additional service that will take up resources
  • Maintainability, Data Consistency, Auto-Scaling together with connection services cost also extra attention
ACl Pattern

6.Command and Query Responsibility Segregation…

This pattern bases on SoC (Separation of Concerns) in terms of database reads and updates. In traditional architectures, the problem of data complexity appears if reads are performing many queries and writes implement very complex validation and business logic. This kind of reads and writes asymmetrical, with different performance and requirements.

Solution here might be CQRS that separates those reads and writes into different components commands for updating, queries for reading:

  • Commands have to be task-based (“Book hotel room”, not “set ReservationStatus to Reserved”).
  • Commands implemented through asynchronous communication
  • Queries never alter the database. A query responses with a DTO that does not hold business logic.

One Drawback in this pattern is holding read and write components synchronized.

CQRS Pattern

7.Event Sourcing…

Event Sourcing Pattern is one of the popular techniques in last decade for the cases where CRUD applications lack of consistency. Instead of just saving the current state (just as in traditional CRUD applications), the main idea of event sourcing is to save data in append-only manner to store the full series of actions taken on the data. It provides consistency for transactional data, maintaining full audit control on edition history.

Advantages:

  • Improves performance by allowing strong data consistency
  • Simplifies the implementation and management of data edition using event store
  • Events are readable for domain experts allowing to be understandable not only for developers
  • Prevents concurrent updates on same data, since its chronology of events
  • event store as a single source of data manipulation

Drawbacks:

  • considered to be an over-engineering for small domain applications
  • not suitable for real-time data driven applications

8.Service Mesh…

In software architecture, a service mesh is a dedicated infrastructure layer for facilitating service-to-service communications between services or microservices, using a proxy.

The main idea is to isolate application-independent cross-cutting concerns such as communication, monitoring, security, authentication/authorization etc. from core business logic. This kind of dedicated infrastructure layer adds value to low latency, configurability.

Beside Authentication/Autorisation, Service Discovery, Service Mesh Pattern provides some other critical capabilities such as:

  • Circuit Breaking
  • Rate Limiting
  • Conditional Rate Limiting
  • Traffic Shifting

9.Dumb-Smart Components (Frontend oriented)…

is the next pattern that SoC initiated. Here we have two kind of components: Dumb components that are only for presentation, Smart Components that are responsible for data flow, separating presentation from data injection. This happens mainly through two-way data binding based on @Input, @Output (EventEmitter) in Dumb Component. With this annotations Dumb Component gets relevant data from Smart Component, or sends data to Smart Component. Smart Components generally injects Service or Facade and copes with data flow. Please See relevant gist here.

10.Unidirectional Architecture (Frontend oriented)…

this mainly incorporates with reactive programming. The data flow in nowadays frontend frameworks are unidirectional, powered with data flow streams. The Data flows only in one direction and it is towards the view. The view will in turn activate different actions. This gives better control over data. Different libraries like RxJs, NgRx, Flux enables multiple functionalities when working with data streams.

There are bunch of other cloud-native patterns, which you can find here.

If you are interested in more Software Engineering topics take a look at my other articles.

Relevant Articles:

  1. 10 Software Design Patterns used in Java Core Libraries
  2. Message Queueing and Event Streaming Providers in Comparison
  3. Documentation as Code Approach in Software Development
  4. How to apply SOLID Software Design Principles to Spring Boot Application
  5. The Ultimate List of Must-Know Kubernetes Commands

P.S. You can connect with me on twitter or linkedin.

Software Architecture
Software Development
Software Engineering
Software
Software Design
Recommended from ReadMedium