Question

How to reference a User Entity from another microservice in ASP.NET Core?

In my microservices architecture using ASP.NET Core, I have two distinct microservices: Identity.API for user management and PersonalAccount.API for handling personal account-related functionalities. Each microservice operates with its own separate database. In PersonalAccount.API, I have a Project entity with a ManagerID field intended to reference a User entity from the Identity.API microservice.

Since Identity.API and PersonalAccount.API are separate projects and databases, there is no direct database-level foreign key constraint possible between them. This situation creates challenges in managing and validating the reference to a user across microservices. I'm seeking guidance on the best approach to handle such cross-service references, ensure data consistency, and maintain integrity between these microservices.

I've attempted to use a foreign key approach between the ManagerID in the PersonalAccount.API and the User entity in the Identity.API. However, this approach is not feasible due to the microservices being in separate databases and not sharing a direct connection. Instead, I considered having PersonalAccount.API make HTTP requests to Identity.API to validate the ManagerID. I expected that by implementing a service-to-service communication mechanism, I would be able to validate the ManagerID and ensure it references a valid User in Identity.API.

What actually resulted was a more complex implementation involving additional service calls and potential performance overhead. I am now looking for a more streamlined approach to manage this cross-microservice reference effectively.

 2  49  2
1 Jan 1970

Solution

 0

I can really recommend the whole microsoft learn course ".NET Microservices: Architecture for Containerized .NET Applications" at https://learn.microsoft.com/en-us/dotnet/architecture/microservices/ which is also available as a pdf download

More specifically, you asked about How to achieve consistency across multiple microservices and microsoft unmistakably says "No microservice should ever include tables/storage owned by another microservice in its own transactions, not even in direct queries"

That said I see two possible solutions:

  1. the synchronous pattern (that you already designed by making HTTP requests to Identity.API) guarantees consistency but has the overhead and may have performance implications
  2. the asynchronous way would be working with eventual consistency by using an event-based communication

Edit: You should also read Identify domain-model boundaries for each microservice on how to store and work with data owned by another microservice (bounded context)

2024-07-19
MxNbrt

Solution

 0

What actually resulted was a more complex implementation involving additional service calls and potential performance overhead.

Yes, that is the cost of the microservices architecture. You move the complexity from let's call it "app"/"domain" level to a higher one. Which can result in overall solution complexity actually rising (and performance overhead too). That is one of the reasons why microservice architecture is quite sensitive to correct design/splitting approach.

I am now looking for a more streamlined approach to manage this cross-microservice reference effectively.

There are several ways to mitigate complexity and/or performance overhead here.

First is the data duplication - Identity service will expose a way to track changes to the owned data (usually this is done in async manner via some queue) and the PersonalAccount service will use it to monitor this changes and store relevant data "locally" in a "read-only" replica (in database and/or cache) and will use it to perform validations, enrich data without requests to the owning service, etc. . This is a very common approach in microservice architecture - see for example Basic microservice design problem re shared data .

Another approach is to introduce some intermediate service responsible for the feature. It can be a Backends for Frontends (BFF) or some orchestrator which will handle "cross-domain" data validation and send appropriate queries/commands to both services.

See also:

2024-07-20
Guru Stron