14

You can't please everyone. Some people want a lot of context and background on sites like this. Others do not. If you don't want the background, skip the first three paragraphs.

I am a software architect with about 25 years experience, starting with Amiga Basic, then C, then C++, VB6, delphi, C#, SQL (server), and more C#. Over the last 15 years my focus has been on back ends - databases, data models, and systems integration (not UI development, and certainly not modern web development with giant javascript libraries)

I currently work in a reasonably large "enterprise". By "enterprise" I mean "not a software development company". By "reasonably large" I mean our software ecosystem includes such things as an ERP (vendor code), a CRM system (vendor), an HR system (vendor), a few other vendor systems, a data warehouse, a BI stack, and a rapidly growing number of internally developed applications.

The number of internally developed applications is growing rapidly because the business wants to be able to add new functionality that is specific to us, to provide market advantages, or just to be able to move faster than the large vendors, thus providing our monolithic systems. I expect this story will be familiar to many, although it probably won't be quite so familiar to people working for pure software development companies, where you don't have to deal with the problem of integrating with large vendor systems. If you fall into the latter category, please keep this in mind.

Enough general background.

Full disclosure, I am about to conflate "bounded context" and "domain" to some degree. Some people swear that a particular business function - such as order entry - is a single bounded context and is a natural application boundary. Others say it's a domain which can have multiple bounded contexts, which are more granular. So, depending on which camp you fall into, read the following either as "domains" or as "bounded contexts".

I have been deeply studying just about everything to do with microservices, event driven architectures, ESBs, message brokers, and other integration elements at a hectic rate over the last several months, as well as rereading Evan's "DDD", Vernon's "Implementing DDD", Hohpe and Woolfe's "Enterprise Integraiton Patterns", and other famous books. And I have noticed a problem.

There are several different "primary sources" or "patterns" of advice on this topic. They all make good points. And they all contradict each other somewhere. I believe I can make the similarities and differences obvious with some simple diagrams.

Of course, the big question is "what do you want to achieve?". Well, let's settle on things everyone seems to agree on with distributed systems: Given CAP, we are very interested in A and P, not so much C. Eventual consistency is accepted, but we don't want one system to bring down all the rest, and we do want to partition the systems - for example into bounded contexts per Eric Evans' DDD.

So, I want you to picture what at first seems to be a fairly "ideal" architecture according to many high-profile sources, by which I mean it hits all the right notes. We have an order entry (point of sale) system. It's a bounded context. We're not "trying too hard to be microservicey" and creating nanoservices, and we're also not a distributed monolith. It's effectively agnostic about the existence of any other system in the enterprise. It's as decoupled as it can possibly be. It has no hard temporal, logical, or availability dependencies on any other system. It looks something like this:

Decoupled orders bounded context application

One day the business comes along and says "I want order entry (or quoting) functionality in the CRM system".

Oh dear.

Orders plz

Now I think I can describe everything else I need to describe purely with a set images which illustrate the various approaches I've seen advocated over countless books, blogs, articles, lectures, and videos, making the distinction between them clear. I have never seen the options laid out quite this way, and I think doing so demonstrates that as an industry we don't seem to have any "logically sound" solution which meets all of our principles of software architecture - except maybe the last. And I would like to hear people's opinions on what they see.

Personally, I think option 6 is the most - and perhaps only - sane choice. In a couple of places, I mention that shared library/schema definitions are "probably not a real objection". I say this because the business rules are the business rules. There's only one set of business rules for the bounded context of orders. If the business rules change, everyone using those rules has to change. This isn't a devops issue.

Option 1 - UI Integration

Option 2 - API Orchestration

Option 3 - Shared libraries and persistence

Option 4 - Shared libraries only

Option 5 - Shared data only

Option 6 - Shared immutable data only

cngzz1
  • 45
allmhuran
  • 316

2 Answers2

4

I'd go with Option 1.

While you listed some potential downsides, you forgot to mention the upsides of this approach: Primarily keeping the loosest coupling between your CRM and Ordering domains by placing that coupling in the most volatile CRM system (the UI). This means that when the Ordering API changes only the CRM UI needs to respond. This is ideal.

I'd also like to point out that the "downside" of having the CRM ordering system fail when your Ordering domain is down doesn't really sound like a downside to me. Presumably, if your Ordering systems can't take orders... well... you probably don't want other parts of your system to be taking orders. What does the Order UI show when it's down? I'd expect the CRM UI to mirror that.

Furthermore, if we simply rearrange your architecture so that there is only one UI (instead of each service having its own) I think the solution is a little clearer. My experience with micro-services is that they tend to be more representative of your service layer than anything "above".

user3347715
  • 3,234
1

Option X

enter image description here

The question isn't totally clear, so I will summarise first: How to integrate two separate microservice systems. (OP please update your question title if you agree).

Service dependencies are the downfall of microservice architecture. You can actually use Microprocess Architecture between these two systems. see https://colossal.gitbook.io/microprocess/differences/compared-to-microservices. (I am a contributor to this draft standard)

As @king-side-slide correctly said in his answer that the "downside" of an Order system being down isn't really a downside, but the CRM system will need to be able to handle that scenario.

Summarising your Situation:

  • The CRM should be assumed to be undocumented (at least the domain packages, but let's say it's all undocumented)
  • The CRM database is accessible to be read only
  • The Order system components are all fully modifiable and understood.

Microprocess Integration Design:

  • Create a new schema/database OCRM to be colocated with the CRM database. This way it's separate, and the vendor can make schema changes without overwriting any of your functionality.
  • Create OCRM.VIEW_NoDealOrders. eg. select * from CRM.Deals D where Closed=true and not exists (select 1 from OCRM.DealOrders DO where DO.DealID = D.ID)
  • Create a microprocess that batch creates new DealOrders driven by OCRM.VIEW_NoDealOrders with notification link to CRM.Deals#Insert. This microprocess will also connect to the Orders database and work according to order rules. This can double-up on OrderService(s) and start a per-subsystem migration to Microprocess architecture gradually.
  • If there is ever going to be a vendor update, or any UI update to display Order information inside the CRM, that should happen via Database-Web-Gateway and Views on the Order data.

If you are concerned about the Order database being offline at times. Simply have a read-replica of the whole Orders database. The order system should use that for read actions, while writes go to the master.

(Of course there would be more to this, but I had to already use my imagination to demonstration what I have)

Kind Contributor
  • 890
  • 4
  • 13