From Application Integration to Microservices Architecture: a Pragmatic Approach
Today we are going to cover a real-life example showing the different methods to expose business capabilities, from application integration to SOA to microservices architecture.
In this example, let’s dig into an insurance company wanting to expose the business capability of quotation calculation for an insurance policy. Of course, to calculate the best quotation price for one customer, we need to know the existing customer contracts (perhaps to return a lower price for devoted customers).
Method 1: Application integration
Let’s first think in terms of application. We can imagine that the insurance company was managing customers with a CRM application and then they started to develop a new application to manage quotations based on complex algorithms.
Because the list of existing contracts for a customer is managed by the CRM application, the quotation application must first retrieve them.
The first approach is to replicate the data managed by the CRM into a local database, hosted by the quotation application.
The replication can be made either:
- With batches (using an ETL for instance).
- Or rather in an event-driven mode by triggering contract operations as soon as something change in the CRM (using a point-to-point integration or an EAI).
- The quotation application is not tightly coupled with the CRM application. At runtime, the quotation application is autonomous.
- The replica DB is not the company’s master referential for managing customers. It may lead to some data quality issues.
Method 2a: SOA with an ESB
Now let’s shift of paradigm and consider the service as the central enterprise building block where reuse is everything.
We still have two applications, a CRM and a quotation one.
The CRM application exposes a getContract service based on a client ID and the quotation application exposes the calculation service based on a list of contracts.
Based on traditional SOA layers, the most intuitive approach would be to expose a business service on top of these two existing applicative services.
The new service would be owned by the ESB (as a SOAP or a REST web service) and would orchestrate the sub service calls:
- Invoke the getContract service.
- Invoke the quotationCalculation service based on the contract list retrieved with the previous call.
- Send back a synchronous reply to the consumer.
- No more data replication.
- The new business service is tightly coupled at runtime with both applications.
Method 2b: SOA without an ESB
Because SOA does not necessarily mean ESB (even though most SOA implementations are ESB-based), we can think about exposing the business service directly on top of the quotation application.
Instead of being owned and hosted by a middleware layer, the service is exposed directly by the quotation application. It will call first the getContract service, still exposed on top of the CRM application and then calculate the best quotation price.
- No data replication.
- The quotation application is tightly coupled with the CRM application.
Method 3a: Synchronous microservices
One last time, let’s shift of paradigm and consider now microservices as the information system building block. Compared to SOA promoting the share-as-much-as-possible principle, microservices architecture promote the opposite, the share-as-less-as-possible principle.
A microservice has different characteristics among which:
These characteristics are the main drivers of microservices architecture and lead to scalable and resilient platforms insofar as:
- Each service can be scaled independently.
- Failure can be isolated and gracefully managed using circuit-breaker pattern.
We can undoubtedly notice that this method is similar to the first one. Of course the granularity is completely different (from monolithic application to lightweight microservice) but insofar as the IT is generally cyclic, this is not much surprising to notice similarities.
In this example, the quotation microservice exposes a synchronous boundary to calculate the customer quotation (based on REST or Thrift for instance).
This example matches perfectly but if we would have considered a more complex service (with another function already handled by another microservice for instance), the following choice would have to be made:
- Either embedding this external function into our quotation microservice. But if we consider that micro means doing one thing but do it well, we would inevitably lose service cohesion.
- Or coupling the quotation microservice with an external microservice but then it would not anymore be considered as autonomous.
- The quotation service is at runtime autonomous and can be scaled independently from the rest of the platform.
- Even using modern approaches such as event sourcing and CQRS, we are still talking about data replication.
- In complex cases, a cursor must be positioned between service cohesion and service autonomy.
Method 3b: Asynchronous microservices
Let’s now consider two microservices, the former exposing the getContract capability and the latter exposing the quotationCalculation capability.
With this approach, we consider asynchronous interactions between two microservices and between with the consumers. The overall coupling is obviously strongly reduced.
One of the main characteristic of microservices architecture is to promote choreography (without any central component) over orchestration (with a central component).
The global routing logic might be performed:
- Based on publish-subscribe. Each microservice publishes its response to an event bus (in our case the quotation microservice subscribes to contract events and the consumer subscribes to quotation events).
- Based on a logic either predefined by the consumer or distributed to microservice. The interactions between microservices can be done using standards such as Reactive Streams.
Such architectures are also called reactive microservices architecture.
- If two microservices must communication with each other, compared to 3a we can still manage having low coupling and high service cohesion in parallel.
- Global asynchronicity can lead to more complex architectures (in terms of development, monitoring etc…).
- All service consumers are not asynchronous-ready.
As usual, there is not in IT a one-size-fits-all approach. Microservices architecture is obviously the next “big thing” in enterprise integration but it is worth understanding the pros and cons of each architecture type and also remembering our legacy.