Expand my Community achievements bar.

SOLVED

Sharing common data to multiple features in Tab component

Avatar

Level 8

Hello Team,

 

In my AEM application, I have tab component. Kept "Component-1" in 1st Tab item section. In this feature, from backend logic, I am fetching the data from 3rd party application via GraphQL. From this I am getting many details like: values, images list.

 

Now, in 2nd Tab item section, I have kept " Component-2". Here, In this component, I need to fetch the same values as above. But, I do not want to call 3rd party application again from my backend.

Note: I cannot move the logic of calling the 3rd party application via graphQL to javascript.

So, I am thinking about Once I get the data from backend of "Component-1", need to keep this data in cookies, or local storage. Then, utilize the same while displaying the data in 2nd tab item section.

 

Let me know your opinion. Thanks in advance

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

1. Leveraging the request session - Data can be shared within a single page request by accessing the same request session object. However, without a mechanism to reinitialize this object, you can't guarantee its availability across multiple requests.


2. The in-memory cache (and this is purely my belief) - If you stay with a single publisher, in-memory caching will work efficiently. However, moving to different publishers resets the cache, requiring it to be repopulated. Additionally, introducing a new caching layer requires a strategy to invalidate outdated cache entries.

Note: Using this cache method is effective in cases where the page remains consistent, though different components are accessed..

3.Introducing a microservice between AEM and the third-party application could streamline data handling. This microservice can fetch data from the third party, store it (e.g., in a relational database or Redis), and allow AEM to access it as needed. While this setup might require additional resources, another approach could involve storing data in an AEM JCR node with a timestamp. This would allow data to be fetched from the third party once per publisher session and stored within AEM for reuse.



Arun Patidar

View solution in original post

13 Replies

Avatar

Level 5

Hi @Mahesh_Gunaje 

 

Adding my suggestion. 

 

If you are calling JS clientlibs from component level, the call will be triggered based on number of times you have authored the component.

 

Rather than storing the data in cookies / local storage, you can call the javascript client library at page template level

 

Hope this helps

 

Thanks 

Avatar

Level 5

Hi @Mahesh_Gunaje 

 

Have you written JavaScript Ajax call to fetch the data from the third party?


Avatar

Level 5

Hi @Mahesh_Gunaje ,

You can use in-memory caching to optimize repeated data access. Another approach would be to store the response in a service variable.

  1. Create a Common Service with a Service Variable:

    • Implement a service class with a Map variable to act as a cache. Store the API response in this map.
  2. Use an Identifier to Control API Calls:

    • In Component-1's model, generate an identifier that you pass to the service. The service can use this identifier to check if the API needs to be called again.
  3. Reuse Cached Response for Component-2:

    • When Component-2 requests data, pass its identifier to the service. The service will check if the map already has data for this identifier. If the data is present, the service will return the cached response, avoiding an additional API call.

This method allows both components to share data efficiently without redundant API calls.

 

Avatar

Level 8

Hi @PRATHYUSHA_VP 

I cannot move the "calling the GraphQL query" to javascript section. Since, the logic is too heavy to move the logic from java to javascript.

Avatar

Community Advisor

Hi @Mahesh_Gunaje 

You might consider exploring an in-memory caching solution.

One approach is to cache the API response per page and reuse it as needed within the page or based on specific logic.

In our project, we’re using Guava Cache to store responses in memory with a configurable time-to-live (TTL) to efficiently manage cache expiration.

 



Arun Patidar

Avatar

Level 8

Thanks @arunpatidar   @narendiran_ravi   for your help. 

Let me think about some in-memory caching mechanism.

 

One general Query: Is in-memory caching is the solution for component communication in AEM? I mean, I am 100% sure that wherever my 2 components (Component-1, component-2) is used,it is used together only.  That is authored in my Tab component. I mean 1st Tab item: Component-1,  2nd Tab Item - Component-2.

Now, sling model of component-1 has heavy logic to hit the 3rd party GraphQL API and get the response. process it. Passes this to Sightly.

 

 

 

Avatar

Community Advisor

Hi @Mahesh_Gunaje 
In AEM, You generally store content in JCR node and when you need to share the content, you use path reference pattern.

But here you can't use that because data does not exists anywhere in AEM.



Arun Patidar

Avatar

Level 7

@arunpatidarWhat are your thoughts on the following three ideas?I would really appreciate your opinion,

 

1. Leveraging the request session. I am thinking of implementing a mechanism to set an attribute with that data on session. But I believe we need to understand how the current solution handles the session management. Is the site accessible for specific users, or also for anonymous ? etc

2. The in-memory cache (and this is purely my belief) can be a tricky thing and can quickly get out of hand. I think it may work well when the processing is required on one author. But when you are on multiple publishers it will be hard to have control of that data: to know which instance has what data in-memory, to trigger targeted invalidation requests for a specific cache and so on.  Also in AEMaaCS things can get even more messy, because there pods can go up and down as they like, and you cannot build a monitoring tool to manage in-memory stuff. Of course, if is not required to have that level of control, then no worries there.

3. If there is a possibility to introduce (if not already exists) microservices, then we can have one in between the AEM  and the third party app. It will pull the stuff from third-party, save it somewhere (relational db, or a Redis or smth), and then AEM can consume it from there. It will bring basically the data more close to the AEM app and both components can fetch it from there. This also assumes component 1's Java code can be modified and is not like an untouchable legacy thing.

 

Avatar

Level 8

Hi @Tethich 

 

Good that you have brought different approaches here. From beginning, I was wondering, why concrete solution is not there for component communication. I know, AEM architecture, intention is different compare to other CMS application like: Drupal or other CMS.

Your point 3 makes sense for my scenario. Already we have microservice kept in Adobe IO. From my sling model of Component1, I am hitting this Adobe IO(GraphQL API). This microservies passes the GraphQL API to 3rd party application. Getting the response. I can think of some caching the response here.

 

Avatar

Correct answer by
Community Advisor

1. Leveraging the request session - Data can be shared within a single page request by accessing the same request session object. However, without a mechanism to reinitialize this object, you can't guarantee its availability across multiple requests.


2. The in-memory cache (and this is purely my belief) - If you stay with a single publisher, in-memory caching will work efficiently. However, moving to different publishers resets the cache, requiring it to be repopulated. Additionally, introducing a new caching layer requires a strategy to invalidate outdated cache entries.

Note: Using this cache method is effective in cases where the page remains consistent, though different components are accessed..

3.Introducing a microservice between AEM and the third-party application could streamline data handling. This microservice can fetch data from the third party, store it (e.g., in a relational database or Redis), and allow AEM to access it as needed. While this setup might require additional resources, another approach could involve storing data in an AEM JCR node with a timestamp. This would allow data to be fetched from the third party once per publisher session and stored within AEM for reuse.



Arun Patidar

Avatar

Level 6

Hi @Mahesh_Gunaje , the first answer came to my mind is to copy the data using JS. I am assuming on clicking tab 1 some servlet is called and the data is loaded. Take a look at the HTML and can't we use js to pick the details and use them in tab 2 as well? For images, try converting them in base64 form and then copy and then covert back. On clicking tab 2, write a JS function to copy the data from tab 1 to tab 2. Its like updating the string values.