Combined Component #
Jack of all trades. Use third-party software which covers multiple concerns.
Aspects: those of the individual components it combines.
Variants:
- Message Bus [EIP],
- API Gateway [MP],
- Event Mediator [FSA],
- Persistent Event Log / Shared Event Store,
- Front Controller [SAHP but not PEAA],
- Enterprise Service Bus [FSA],
- Service Mesh [FSA],
- Middleware of Space-Based Architecture [SAP, FSA].
Structure: Two or more (usually) extension patterns combined into a single component.
Type: Extension.
Benefits | Drawbacks |
---|---|
Works off the shelf | Is yet another technology to learn |
Improved latency | May not be flexible enough for your needs |
Less DevOps effort | May become overcomplicated |
References: Mostly [FSA], Microsoft on API Gateway, [DEDS] on Shared Event Store.
Two or three metapatterns may be blended together into a Combined Component which is usually a ready-to-use framework which tries to cover (and subtly create) as many project needs as possible to make sure it will never be dropped from the project. On one hand, such a framework may provide a significant boost to the speed of development. On the other – it is going to force you into its own area of applicability and keep you bound within it.
Performance #
A Combined Component tends to improve performance as it removes the network hop(s) and data serialization between the components it replaces. It is also likely to be highly optimized. However, that matters if you really need all the functionality you are provided with, otherwise you may end up running a piece of software which is too complex and slow for the tasks at hand.
Dependencies #
A Combined Component has all the dependencies of its constituent patterns.
Applicability #
Combined patterns work well for:
- Series of similar projects. If your team is experienced with the technology and knows its pitfalls, it will be used efficiently and safely.
- Small- to medium-sized domains. An off-the-shelf framework relieves you of infrastructure concerns. No thinking, no decisions, no time wasted.
Combined patterns are better avoided in:
- Research and development. You may find that the technology chosen is too limiting or a wrong fit for your needs after it has already been deeply integrated into your code and infrastructure.
- Large projects. Most of the combined patterns include an Orchestrator which tends to grow unmanageably large (requiring some kind of division) as the project advances.
- Long-running projects. You are very likely to step right into vendor lock-in. The industry will evolve, leaving you with the obsolete technology you have chosen and integrated.
Variants #
Combined components vary in their structure and properties:
Message Bus #
A Message Bus [EIP] is a Middleware which employs an Adapter per service allowing services that differ in protocols to intercommunicate.
API Gateway #
API Gateway [MP] is a component which processes client requests (and encapsulates the client protocol(s)) much like a Gateway (a kind of Proxy) but it also splits each client request into multiple requests to the underlying services like an API Composer or a Process Manager (Orchestrators).
If the orchestration logic of an API Gateway needs to become more complex, it makes sense to split it into a separate Gateway and Orchestrator, rewriting the latter as a custom Application Service. When there are multiple types of clients that strongly differ in workflows and protocols, one API Gateway per client type is used, resulting in Backends for Frontends. A Cell-Based Architecture relies on API Gateways for isolation of its Cells.
Example: a thorough article from Microsoft.
Event Mediator #
An Event Mediator [FSA] is an orchestrating Middleware. It not only receives requests from clients and turns each request into a multi-step use case (as does Orchestrator) but it also manages instances of the services and acts as the medium which calls them. Moreover, it seems to be aware of all the kinds of messages in the system and which service each message must be forwarded to, resulting in an overwhelming complexity concentrated in a single component which does not even follow the separation of concerns principle. [FSA] proposes countering that by using multiple Event Mediators split over the following dimensions:
- Client applications or bounded contexts, dividing the Event Mediator’s responsibility by subdomain.
- Complexity of a use case, with simple scenarios handled by a simple first-line Event Mediator and the more complicated scenarios being forwarded to second- and third-line Event Mediators which employ advanced orchestration engines.
Either case, strangely, results in multiple Middlewares connected to the same set of services.
The Event Mediator pattern seems to be well established but, obviously, it may become quite messy for larger projects with nontrivial interactions. Such cases may also be solved by separating the Middleware from the Orchestrator and dividing the latter into Backends for Frontends or Top-Down Hierarchy.
Example: Mediator Topology in the [FSA] chapter on Event-Driven Architecture.
Persistent Event Log, Shared Event Store #
When a Middleware grants long-term persistence, it becomes a Shared Repository. This may happen to an Event Log which implements interservice communication.
On the other hand, a shared Event Store, which persists changes of internal state of services and replaces the services’ databases, may be extended to store interservice events, taking the role of a Middleware.
Either case makes changing the event schema troublesome because either all the services that read the event will need to support multiple (historical) schemas or you’ll have to overwrite the entire event history, translating the old schema into a new one.
Example: [DEDS] shows this implemented with Apache Kafka.
Front Controller #
Front Controller [SAHP but not PEAA] is the name for the first (client-facing) service of a pipeline in Choreographed Event-Driven Architecture when that service collects information about the status of each request it has processed and forwarded down the pipeline. The status is received by listening for notifications from the downstream services and is readily available for the Front Controller’s clients, resembling the function of Query Service (Polyglot Persistence) and Application Service (Orchestrator).
Enterprise Service Bus (ESB) #
An Enterprise Service Bus (ESB) [FSA] is a mixture of Message Bus (with a stack of Adapters per service) and Event Mediator (built-in Orchestrator) which turns this kind of Middleware into the core of the system. The combination of a central role in organizations and its complexity was among the main reasons for the demise of Enterprise Service-Oriented Architecture.
Example: Orchestration-Driven Service-Oriented Architecture in [FSA], how it is born and how it dies by Neal Ford.
Service Mesh #
A Service Mesh [FSA] is a Middleware that employs one or more Sidecars [DDS] per service as a place for cross-cutting concerns (logging, observability, encryption, protocol translation). A service accesses its Sidecar without performance and stability penalties as they are running on the same machine. The totality of deployed Sidecars makes a system-wide virtual layer of shared libraries: though the Sidecars are physically separate, they are often identical and stateless, so that a service that accesses one Sidecar may be thought of as accessing all of them.
A Service Mesh is also responsible for dynamic scaling (it creates new instances if the load increases and destroys them if they become idle) and failure recovery of the services. Last but not least, it provides a messaging infrastructure for the Microservices to intercommunicate.
Middleware of Space-Based Architecture #
Space-Based Architecture [SAP, FSA] relies on the most complex Middleware known – it incorporates all four of the extension metapatterns:
- The Messaging Grid is a Proxy (combination of Gateway, Dispatcher, and Load Balancer) that receives, preprocesses, and persists client requests. Simple requests are forwarded to a less loaded Processing Unit (service with business logic) while complex ones go to the Processing Grid.
- A Processing Grid is an Orchestrator which manages multi-step workflows for complex requests.
- A Data Grid is a distributed in-memory database. It is built of caching nodes which are co-located with instances of Processing Units, making the database access extremely fast. However, the speed and scalability is paid for with stability – any data in RAM is prone to disappearing. Therefore the Data Grid backs up all the changes to a slower Persistent Database.
- A Deployment Manager is a Middleware that creates and destroys instances of Processing Units (which are paired to the nodes of the Data Grid), just like Service Mesh does for Microservices (which are paired to Sidecars [DDS]). However, in contrast to Service Mesh, it does not provide a messaging infrastructure because Processing Units communicate by sharing data via the Data Grid, not by sending messages.
The four layers of the Space-Based Architecture’s Middleware are reasonably independent. Together they make a system that is both more scalable and more complex than Microservices.
Evolutions #
The patterns that involve orchestration (API Gateway, Event Mediator and Enterprise Service Bus) may allow for most of the evolutions of Orchestrator by deploying multiple instances of the Combined Component which differ in orchestration logic. There is also one unique evolution:
- Replace the Combined Component with several specialized ones
Summary #
A Combined Component is a ready-to-use framework that may speed up development but will likely constrain your project to follow its guidelines with no regard to your real needs.