10

Within an enterprise distributed system I have many services - an E-commerce service, a CRM, support desk, finance, billing. Many of these services share common data, such as Customer data.

These services communicate with each other using an Enterprise Service Bus (ESB) to ensure that data in all systems is eventually consistent with one another.

My question is this: Is it better to ensure that only one system can update any one part of data? To have a single source of truth. E.g. Only the billing system can update the Customer's billing information. Only the CRM can update the Customer's contact details?

To me this sounds cumbersome and confusing to locate the correct system for the data that you wish to update. I can see it better to have multiple sources for updates and the ESB communicates these updates to subscribed services.

I can see that some data will have a single source of truth (SSOT) as it would be quite niche, such as Customer's credit card information, for example.

What is an commonly adopted technique for dealing with common data that could potentially be updated from different services? Is a SSOT needed in an enterprise distributed system?

MrDeveloper
  • 279
  • 2
  • 11

1 Answers1

11

The most architecturally sound approach I know of is to put that single source of truth behind a microservice. It is perfectly okay for multiple parts of the system to update that data, as long as they do it through something like a microservice that can ensure it's always done correctly and predictably.

So for instance, Customer data is probably already in a database, but all reads and writes of Customer data should go through a single service whose sole purpose is to provide a limited interface for manipulating Customer data. This provides a common place for things like validation logic and query optimization, and ensures that changes to the data always happen in very specific ways you've thought about in advance and are sure will be okay. For instance, you may provide a deleteCustomer request that ensures all credit card data for that customer also gets deleted when the customer does. This also makes it much easier to change the underlying database tables in the future.

Finding the correct microservice should be no harder than finding the correct database tables, and the microservice's API should be significantly easier to use correctly than a database schema. Also, it should be a very thin wrapper; most of the ones I use and write at work simply map each request to a single SQL statement. More interesting logic like using credit card details to charge someone or setting up delivery of their item belong elsewhere.

Ixrec
  • 27,621
  • 15
  • 80
  • 87
  • If I understand your answer correctly, you are talking about a common object model across each service, each needing common validation, which makes perfect sense. However I'm using a different bounded context for each of my disparate services, so a Customer in one context can be quite different to a Customer in another context. In this scenario is there still a need for a SSOT in a distributed system ? – MrDeveloper Jun 30 '15 at 10:42
  • Could you be a little more specific about what you mean by "different in another context"? My knee-jerk answer would be either "you have two types of Customer, so you need two SSOTs" or "the differences should be all in the application logic, not part of the Customer object itself", but I'm not sure if that would help much. – Ixrec Jun 30 '15 at 11:13
  • A quick example would be a Customer in a helpdesk system would potentially have tickets, whereas a Customer in a ecommerce system would have orders and line items. So yes, they are 2 different types of customers, not exposed to other systems outside their own bounded context. – MrDeveloper Jun 30 '15 at 11:36
  • I would consider that data associated with a Customer, but not part of the Customer itself or different types of Customers. The SSOTs/microservices/whatevers for tickets, orders and line items should probably check that they have a valid customer id (which could be as simple as a foreign key constraint), but they should still be separate from the SSOT/microservice/whatever for Customer itself. Otherwise these services would not be very "micro". – Ixrec Jun 30 '15 at 11:40
  • @MrDeveloper So you have no reliable way to associate my help desk requests with my orders? Or to ensure that someone else is not calling the help desk and modifying my orders. The amount of data require for the two uses may be different (possibly customer sub-types), but I would argue you may want a central customer database. – BillThor Jun 30 '15 at 12:45
  • @BillThor The Customer object shares a unique global identifier across all services so a user of the system can cross reference Orders to Tickets for example, but as Ixrec says these are data that is associated with a Customer. The unique Id is generated when the Customer is first generated by one service, then dispatched onto the ESB (`CustomerCreated { guid:uniqueId }`) for all other Services to create their own Customer with this unique Id. The unique Id is held by each system independently. Is essence a Customer is just an Id, but has no centralised store to hold it. – MrDeveloper Jun 30 '15 at 13:14
  • 1
    @MrDeveloper So you have significant duplication of data with no way of resolving conflicting data. (You're answer verifies that you do have customer sub-types.) Look at normalizing the sub-types. Caching or replicating sub-type locally in individual sub-systems could make sense. – BillThor Jun 30 '15 at 13:38
  • @BillThor I wouldn't say there is significant duplication between the different microservices. Just the Id and perhaps the Customer name. Each microservice essentially holds its own SSOT with regards to its context. Ixrec touched on this in his first paragraph of his answer. An EcommerceCustomer is different to a BilledCustomer, both have different SSOT as both are disparate models with separate responsibilities, but they share the same Id. – MrDeveloper Jun 30 '15 at 13:56
  • @MrDeveloper So no addresses, phone number, email addresses, etc? – BillThor Jul 01 '15 at 02:06
  • @BillThor Not necessarily no. An ecommerce platform has, theoretically, no need for address, phone number, email address. Those would be part of the CRM system and a notification system. It all comes down to carefully thought out and constructed aggregates to reduce the amount of duplication across the disparate systems. Sometimes duplication is needed for sake of convenience, I don't disagree with that, but again each case would need to be considered individually rather than just having the same approach for what seem like 'common' attributes. – MrDeveloper Jul 01 '15 at 08:18
  • @MrDeveloper So ecommerce has no shipments, delivery notifications, marketing capabilities? – BillThor Jul 01 '15 at 16:18
  • @MrDeveloper By the way, you can ask a new, more specific question if you would like additional, more specific advice about how best to design these systems. That usually works better than a discussion in comments. – Ixrec Jul 01 '15 at 19:13