neo4j - are we going to duplicate the domain entities across multiple microservices to avoid application join

I am planning to migrate existing services from mongodb to neo4j graphdb for persistence. I have profile and order service that uses mongo backend. My order domain entity has reference to profileId and I use application code to join Order and profile based on the profileId. Now if I choose neo4j, I want to avoid application code to join but use neo4j way to do simple to complex joining requirement. Now, the question is how would I avoid that in design given profile and order are in 2 different microservices? How would I model in neo4j efficiently and define relationship between profile and order when they are present in 2 microservices within bounded context. Am I going to duplicate profile and order entities to define the relationship. Please help.

For e.g. scenerios like below:

  1. Some business transactions must enforce invariants that span multiple services. For example, the Place Order use case must verify that a new Order will not exceed the customer’s credit limit. Other business transactions, must update data owned by multiple services.

  2. Some business transactions need to query data that is owned by multiple services. For example, the View Available Credit use must query the Customer to find the creditLimit and Orders to calculate the total amount of the open orders.

  3. Some queries must join data that is owned by multiple services. For example, finding customers in a particular region and their recent orders requires a join between customers and orders.

PS. quoted from database-per-service design pattern

1 answer

  • answered 2018-04-17 05:30 Rebecca Nelson

    If you are using database-per-service, then joining across databases is by definition an out-of-band operation; there is no way to leverage Neo4J's joining efficiency across different databases.

    Another option I could see would be to have each microservice use the same database backend, but if you are intent on using database-per-service, that is not possible.

    If you're feeling particularly adventurous and crafty, I suppose it would be possible to add this functionality using a lot of custom coding to have Neo4J reach out to other instances to perform joins, but this will still be much slower than if the entities resided in the same database, as it would require reaching out over the network.

    In addition, the above solution would still be out-of-band processing, and quite possibly starts to smudge the separation of concerns that comes with the microservices architecture. Whether that is okay would be up to you.