I was not sure how to title this question, but bear with me.

My company is building a new product and for it we will use a third-party service (let's call it ENB for short) to be responsible for many operations on our data that are not our core business. It's in .NET Core if it matters.

To illustrate I will use the entity ApplicationUser, which is the user that logs in to our application. ApplicationUser will consist of account data as well as a Person, representing the real life person that created this account. To function, ENB needs the Person object and most of its data to function, so we have to create the Person object in ENB. This puts us in a situation where if we store the Person in both our database and in ENB, we will have duplicated the data which rings all kinds of alarm bells in my head.

public class ApplicationUser
    public int Id { get; set; }
    < ... other fields ... >
    public int EnbPersonId { get; set; }  // This is stored in ENB

The above is the case for many of our entities: ENB needs their data to function so we have to store it there. For others, part of the fields of a domain object are specific to our application and parts are needed by ENB. This is why I say that the schema is split across sources.

One solution to this is to prefer storing in ENB whenever it's needed, and store the rest (as said, sometimes parts of an entity) in our database. Then, whenever a type is needed, we assemble it by querying both our own database as well as calling ENB through API (we don't have direct access to ENB's database).

Another solution is to simply duplicate the data. This instinctively feels bad because we have to update two sources whenever anything is changed, and we have to make sure they stay in sync (what happens if one update fails and the other doesn't?).

What I'm looking for is if any solution is better than the other, and if there is a name for this pattern of splitting a schema across multiple sources i.e. our own and ENB.

  • im unclear on why you need the person data locally. why not just use ENB
    – Ewan
    Jan 23 '20 at 10:37
  • @Ewan Because we need to use the Person data in our application to show the user. As I said the Person object will be stored only in ENB since the all the fields related to a Person are available in ENB, but if we take another example like Product there may be fields that we need that aren't available in the API that ENB provides. In that case we should store the fields that we can't store in ENB in our own database.
    – Jokab
    Jan 23 '20 at 11:39
  • i mean, get Person by calling ENB whenever required, store non Person objects on other systems
    – Ewan
    Jan 23 '20 at 11:41
  • @Ewan Sure, yes, that's what I'm suggesting as the first solution. This is however not something I've done before in that our domain objects consist of data from multiple sources, and to me it seems unintuitive. But maybe it's common practice, which is why I sought a pattern name. But if a pattern doesn't exist, is it really something people do, and if not, is there a more common solution to the problem?
    – Jokab
    Jan 23 '20 at 11:57
  • thats not what i mean though, Person is fully in one domain, Product in another. there is no half and half obj
    – Ewan
    Jan 23 '20 at 12:26

When it comes to business logic we agree that DRY principle is a cornerstone of structuring it well. However, this is not always true for the database world.

The main reason is that assembling needed information from different sources requires additional costs. If we talk about the same database-scenario this is what denormalization is for: sometimes you let your data to be duplicated in order to improve your select-intensive application. We can extrapolate this pattern for your case with multiple sources: in case querying data for your system is prevalent you may want to duplicate your data. Otherwise, you shouldn't do it.

what happens if one update fails and the other doesn't?

This is a tricky question. In the scenario with a single database transactions would be a natural answer. However, for your case, you may try to emulate transactions programmatically. I enjoy the idea of compensating actions in case when part of your "transaction" fails. The link I've provided mentions microservices but still, I think it's sufficient for you to capture the essence.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.