We're building a new web-based industrial application and one of the questions that are hammering our heads for the last few days is about the integration between different "microservices" on this architecture.
I'm using microservices with just a pinch of salt because we're not totally embracing the concepts to define real microservices. One (and I think the biggest) difference relies on the fact that we're using the same shared database along the different modules (that I'm calling "microservices"). A sort-of logical view of our system could be drawn as:
╔══════════════╗ ║ Client ║ ══╗ ╚══════════════╝ ║ (2) ║ ▼ ╔══════════════╗ (1) ╔══════════════╗ ║ Serv. Reg. ║ <==> ║ API Gatew. ║ ╚══════════════╝ ╚══════════════╝ █ █ █████████████ (4) █ █ ████ ╔══════════════╗ ╔══════════════╗ ╔══════════════╗ ║ Module A ║ ║ Module B ║ ║ Module C ║ <===== "Microservices" ╚══════════════╝ ╚══════════════╝ ╚══════════════╝ ║║ (3) ║║ (3) ║║ (3) ║║ ║║ ║║ ╔══════════════════════════════════════════════════╗ ║ Database Server ║ ╚══════════════════════════════════════════════════╝
Some things that we've already figured out:
- The Clients (External Systems, Frontend Applications) will access the different Backend Modules using the Discovery/Routing pattern. We're considering the mix of Netflix OSS Eureka and Zuul to provide this. Services (Modules A,B,C) registers themselves (4) on the Service Registration Module and the API Gateway coordinates (1) with the Register to find Service Instances to fullfill the requests (2).
- All the different Modules use the same Database. (3) This is more of a client's request than a architecture decision.
The point that we (or me, personally) are stuck is about how to do the communication between the different modules. I've read a ton of different patterns and anti-patterns to do this, and almost every single one will tell that API Integration via RestTemplate or some specialized client like Feign or Ribbon.
I tend to dislike this approach for some reasons, mainly the synchronous and stateless nature of HTTP requests. The stateless-ly nature of HTTP is my biggest issue, as the service layer of different modules can have some strong bindings. For example, a action that is fired up on Module A can have ramifications on Modules B and C and everything needs to be coordinated from a "Transaction" standpoint. I really don't think HTTP would be the best way to control this!
The Java EE part inside of me screams to use some kind of Service Integration like EJB or RMI or anything that does not use HTTP in the end. For me, it would be much more "natural" to wire a certain Service from Module B inside Module A and be sure that they participate together on a transaction.
Another thing that needs to be emphasized is that paradigms like eventual inconsistencies on the database are not enough for our client, as they're dealing with some serious kind of data. SO, the "I promise to do my best with the data" does not fit very well here.
Time for the question:
Is this "Service Integration" really a thing when dealing with "Microservices"? Or the "Resource Integration" wins over it?
It seems that Spring, for example, provides Spring Integration to enable messaging between services as would a tech like EJB do. Is this the best way to integrate those services? Am I missing something?
PS: You may call my "Microservices" as "Microliths", how we usually name them around here. :)