158
Views
4
Comments
Cyclic reference | ODC

Hello Community,

I am currently working on a complex OutSystems application and have encountered a challenge with managing circular references in a microservices architecture. Here’s an overview of my setup:

Context:

  • Microservices Setup: My application is structured around multiple microservices, each handling specific functionalities. For simplification, I’m focusing on three key microservices:
    • Core Concepts Microservice: This handles core functionalities like managing spaces.
    • IDP Microservices: These manage integrations with various Identity Providers (IDPs) like Entra IDP and Google WorkSpace IDP. Users can connect multiple IDPs for login purposes.
    • User Microservice: This handles user management and needs to reference the IDP microservices.
  • I’ve had to implement custom logic for the IDP integrations because the OutSystems OAuth2 IDP configuration process cannot be programmatically handled in a way that meets our requirements.

Problem:

I’m facing a challenge where:

  1. The Core Concepts Microservice contains a Space table that is referenced in the IDP microservices for authentication purposes.
  2. The User Microservice also references these IDP microservices to handle user authentication across different spaces.
  3. Additionally, I need to include audit fields in the Core Concepts Microservice (e.g., SpaceBranding table) to track who made changes.

Concern:

This architecture, as simplified in the attached diagram, creates a circular dependency between the microservices. My concern is how to best manage these circular references, considering the complexity added by the custom logic and the need for cross-referencing between microservices.

Question:

  • What are the best practices to avoid or manage circular references in a microservice architecture like this, particularly when custom integration logic is involved?
  • Are there recommended patterns in OutSystems to handle such dependencies effectively?

Looking forward to any advice or experiences you can share!

Attached: Simplified system diagram


Screenshot 2024-08-02 104657.png
2019-07-25 15-17-44
Christopher Robin-Kennedy

Seems like there are too many services hosted in the Core concepts app? are you able to split some of the services in the Core Concepts out into seperate Apps? 

like so?


UserImage.jpg
Bernardo Cabral

Currently, the Core Concepts microservice is responsible for two main areas:

  • Spaces (tenants): Which manages tenant-specific data.
  • Global Values: Which includes static entities and settings applicable across the entire system.

Splitting this into separate microservices, such as a Space Microservice and a Global Values Microservice, does seem logical. However, I foresee challenges with managing references between these microservices:

  1. IDPs and Spaces: The IDP microservices need to reference the Space microservice to determine the tenant context for authentication. This creates a dependency that could lead to circular references

  2. Audit Fields: The requirement to track who made changes (audit fields) adds another layer of complexity. For instance, in the IDP microservices, audit data needs to be tracked but references back to the User or Space microservices might introduce circular dependencies.

Potential Solution:

To mitigate these circular dependencies, I’m considering creating a dedicated Audit Microservice that could manage all audit trails independently across the different microservices. This would:

  • Decouple the audit logic from the core business logic.
  • Reduce direct dependencies between microservices, as they would only need to interact with the Audit Microservice for recording changes.
New Arch.drawio.png
2023-10-19 05-09-59
Mangesh Phanse

Hi Bernardo Cabral

Without changing or migrating any thing within curent microservices you can take of circular references as follow.

1 - CoreConcepts:

Core concepts micri service has business logic

2 - Authentication Service:

This service authenticates with external service provider and gets claims from third party. Uses those authorize in UserIDP and generates tokens required for CorceConcepts

3 ,4,5 are External Providers idp and user

6 - Generic audit

basically it stores the Audit information

From my experience generic audit should store

1 - AppName

2 - Entity Name

3 - Primary key of record (in long integer type)

4 - Changes in the field

So this app dont need any reference etc. While fetching respective microservice actions can use above 4 fields to have joins with internal entities.





2024-09-08 11-13-40
Nuno Damaso
 
MVP

Hi Bernardo,

I feel like your first diagram was surrounding technical concepts and this is hard to tackle when managing complex architectures surrounding microservices. 

If instead you take a DDD approach, where your second diagram leans a bit more to it, I can identify 3 contexts:

  • Authentication
  • Audit
  • Shared Kernel (what you call global values)

I would work on having just these 3 apps. I don't think it's likely that your Idps will scale independently or need different sponsors and teams for development (if it is then they would represent a context by themselves and could justify another app). 

This is likely the case for the User and Space(tenants) concepts/apps as well, they all seem to be a part of this context of your authentication domain. I would group these in an Authentication concept, this will ultimately simplify the whole thing.


If I'm wrong here for some reason and you have an absolute need to scale these things individually and the "Authentication" domain is not a fit, then your detach of Space is one way to solve it, BUT here's another take:

If your Space means something in an Authentication context, but another in, say, a Branding context, then these things are not the same in a DDD approach. Sure, you'd have to repeat a Space modeling in different apps (different entities with the same name) and have a context mapping service to map said Spaces between the Authentication domain and your Branding domain, but that's the way to go.

It is a lot easier in my experience to model these thing from a Domain view instead of the lower service level.


A final thought is that these "cyclic references" between loosely coupled apps are usually something to look at and may be a red flag, but they are not per se a violation of anything, there are conditions where its ok as long as your services/events are loosely coupled and you have proper bounded contexts on your apps.



Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.