As far back as 2003, Gartner declared ‘Event-Driven Architecture’ (EDA) to be “next big thing” to follow on the heels of ‘Service-Oriented Architecture’ (SOA); itself still in its infancy in 2003. Since then, SOA has overtaken the world; yet EDA remains confined to adolescence. This is indeed curious, as the two architectures were declared at the time to be entirely “complementary”.
“One of the main advantages of the SOA approach is that by building standards-based interfaces between components, developers can incrementally construct applications and swap out, reuse and modify components without having to concern themselves with their inner workings”. Nonetheless, Gartner declared EDA to be “More efficient than the SOA approach if there are multiple destinations for the same data, because the source sends the event only once. An SOA-based client would have to make successive calls”.
This is because “In a [SOA] Web services scenario, the communication between the service consumer and the service is typically done via [point-to-point] request-response, through XML-based messages sent via the Simple Object Access Protocol over HTTP”. Consequently, in SOA, “connecting services occurs in a linear, predictable sequence, whereas an event-driven architecture allows for multiple, less predictable, asynchronous events to happen in parallel and trigger a single action”. Precisely how asynchronous events could be used to “trigger a single action” was never explained.
If we fast-forward almost 20 years, we can read about the — increasingly abandoned — ‘next big thing’ in software architecture, in Microsoft’s Communication in a microservice architecture: “A microservices-based application is a distributed system running on multiple processes or services… Each … microservice owns its own data and its own domain logic… The two commonly used [inter-service communication] protocols are HTTP request/response with resource APIs (when querying most of all), and lightweight asynchronous messaging when communicating updates across multiple microservices”.
As such, some 20 years after Gartner’s suggestion that we use “asynchronous events to … trigger a single action”, it would appear that asynchronous messaging is still only being used “when communicating [business entity] updates across multiple microservices”. That it is instead for synchronous “HTTP request/response with resource APIs” to issue ‘commands’ to other microservices; “when querying most of all”.
“A microservice-based application will often use a combination of these communication styles. The most common type is single-receiver communication with a synchronous protocol like HTTP/HTTPS when invoking a regular Web API HTTP service” (as per SOA). “Microservices also typically use messaging protocols for asynchronous communication between microservices” (just like EDA). However, the use of asynchronous communication is apparently limited today to “propagating data updates between multiple microservices through events”.
Despite this reality, we are urged by Microsoft to “never depend on synchronous communication (request/response) between multiple microservices, not even for queries”; not even to invoke ‘commands’. “If your microservice needs to raise an additional action in another microservice, if possible, do not perform that action synchronously and as part of the original microservice request and reply operation. Instead, do it asynchronously (using asynchronous messaging or integration events … etc.)”.
Given this, nearly 20 years after the announcement of Gartner’s “next big thing” — ‘Event-Driven Architecture’ — we are once again being urged to only ever “raise an additional action in another microservice … using asynchronous messaging or integration events”; once again without the slightest indication as to how this might be achieved. One possible explanation for the now two-decades-old absence of just such a paradigm, is the definition of ‘event-based communication’ used by Cloud giants such as Microsoft: “a microservice publishes an event when something notable happens, such as when it updates a business entity. Other microservices subscribe to those events. When a microservice receives an event, it can update its own business entities”, thereby “bringing domain state in sync across multiple microservices or external systems”.
If we abide by such a definition when implementing ‘event-based communication’, events should in fact never be used to invoke commands (e.g. queries), but should only ever be published after “something notable happens”; precisely why events — unlike commands — are always named using past participles. Commands, conversely, always come before “something notable happens”, not after; a command is indeed the catalyst of that ‘something’ (“such as when it updates a business entity”). The rather linear implication of this is that ‘event-based communication’ cannot possibly be used to “raise an additional action in another microservice”: to invoke a ‘command’. It is therefore perhaps unsurprising that Microsoft itself informs us that REST — “A popular architectural style for [synchronous] request/response communication” — “is the most commonly used architectural communication approach when creating services” today.
The good news is that we can escape from this grammatical conundrum by simply broadening our perception of what constitutes: “updates [to] a business entity”. To this end, I would like to propose a new ‘Requested Event-Pattern’. The idea is this: if Software Component A publishes a ‘Quote.Requested’ Event — for example — then any other Software Components subscribed to the ‘Quotations’ Topic would receive this Event (in real-time), and could act upon it as they choose. Both Software Components B and C could — using the same example — decide to create new Quotations, and each to publish their own individual ‘Quote.Created’ Events. Such an outcome would be exactly that desired by Software Component A; although it never issued any ‘command’.
Having said that, what is implicit in the example just given, is that ‘Create’ is the default (underlying) command of any ‘Requested’ Event. This is not to say however, that a Requested Event Payload could not equally carry other ‘Requested’ commands/verbs, such as Delete, Update, etc., along with the corresponding identifier. It is likewise easy to imagine modelling the same Pattern as ‘CreateAsked’, ‘UpdateAsked’, ‘DeleteAsked’, etc., to facilitate Request-Response matching.
What must be pointed out in the ‘Requested’ Event-paradigm, is that the source Application ought to include ‘Source-Application Request’ identifiers when publishing such a ‘Quote.Requested’ Event, and that those same identifiers should be included in any ‘Quote.Created’ Event Payloads that result; or there will be no possibility for the source application to correctly identify any subsequent ‘Quote.Created’ Events pertaining to its original ‘Quote.Requested’ Event. That is unless the source application opens a new ‘Application-specific Topic’ prior to publishing its first ‘Requested’ Event; the results of which (e.g. ‘CreateFailed’) would necessarily be published to that same (AppUUID) ‘Callback Topic’, for which there will only ever be a single subscriber (see ‘Model-View-Broker Pattern’: https://camhunt.medium.com/eda-model-view-broker-pattern-the-new-mvc-c83940f99453). Any successfully processed — and therefore State-changing — ‘Requested’ Events, must likewise result in an identical (success) Event being published in the public Entity Type Topic (e.g. ‘Quote.Created’).
Regardless of which approach is used, it isn’t very difficult to argue that the ‘Quote.Created’ Events do not in fact represent the very first “notable … updates [to] a business entity”; they do not after all, arise from nowhere. Instead, the ‘Requested’ Event should be legitimately considered as the first ‘notable’ step in the creation of a new Entity: a ‘Draft Entity’ that we can address from the very beginning via its ‘Source-Application Request’ identifiers, and regardless of the fact that the consequent Entity/Entities will not be given unique identifiers of their own until the resultant ‘Created’ Event(s) — which is entirely proper given that we have no idea how many concrete entities (e.g. Quotations) might eventually be created from each ‘Draft Entity’.
As Microsoft confirms, in cases where “Each request can be processed by zero to multiple receivers … communication must be asynchronous”. In other words, such a ‘Quotation Scenario’ cannot even be modelled using the REST architectural style: Software Component A can never know what other Software Components are subscribed to the ‘Quotations’ Topic at any given time (of which there can be zero-to-many). But what of target Software Components unable to support this newer ‘pub/sub’ architectural style without prohibitive rework? To implement the ‘Requested Event-Pattern’ in such cases, some middleware component is simply required to map any published ‘Requested Event’ to its necessary, individual REST calls (until they are eventually swapped-out). The Event Broker itself might even be enhanced to support this mapping, and therefore a (decoupled) two-step transition towards a — true — Event-Driven Architecture.
As an added bonus, the adoption of the proposed ‘Requested Event-Pattern’ would likewise eliminate one of the greatest pain-points in microservice development: ‘API-versioning’. This dilemma can be altogether removed by making use of ‘Version-Stacking’ in (JSON) ‘Event Payloads’ (something I outlined in an earlier Blog:
It is now time for ‘Event-Driven Architecture’ to emerge from its long and lonely adolescence. EDA is — once again — the “next big thing” in software architecture.
Event-driven architecture poised for wide adoption
LOS ANGELES -- Just as many IT shops are starting to get their arms around the service-oriented architecture (SOA)…
Communication in a microservice architecture
In a monolithic application running on a single process, components invoke one another using language-level method or…