Wanted to understand data/logic flow of product component of CIF | Community
Skip to main content
Level 7
August 9, 2024
Solved

Wanted to understand data/logic flow of product component of CIF

  • August 9, 2024
  • 1 reply
  • 983 views

 

Hi Team,

Can someone please explain me the logic of the CIF component: /apps/core/cif/components/commerce/product/v3/product
Foe testing purpose, I have deleted all the content from /apps/core/cif/components/commerce/product/v3/product/productFullDetail.html
Stil, in the logs I can see:
com.adobe.cq.commerce.core.components.client.MagentoGraphqlClient Cache hit for query
'{products(filter:{url_key:{eq:"carina-cardigan"}}){items{__typename,sku,url_key,name,description{html},image{label,url},thumbnail{l ....

That means, even if we are not rendering anything from Sightly component, still backend logic calls the GraphQL query to get the data.
Ofcourse, Sling model is called from: /apps/core/cif/components/commerce/product/v3/product/product.html

Can someone tell where exactly the logic is written to the GraphQL response:
I can see com.adobe.cq.commerce.core.components.models.retriever.AbstractProductRetriever
Here, method:

 

@Override protected void populate() { // Get product list from response GraphqlResponse<Query, Error> response = executeQuery(); errors = response.getErrors(); if (CollectionUtils.isEmpty(errors)) { Query rootQuery = response.getData(); List<ProductInterface> products = rootQuery.getProducts().getItems(); // Return first product in list unless the identifier type is 'url_key', // then return the product whose 'url_key' matches the identifier if (products.size() > 0) { product = Optional.of(products.get(0)); } else { product = Optional.empty(); } } else { product = Optional.empty(); } }

 

Is this, the logic to get the particular product details. If yes, which method calls this. I was traversing through : com.adobe.cq.commerce.core.components.internal.models.v3.product.ProductImpl and then its super classes to crack the logic. Still, I am bit confused here.

Can someone help to crack the logic of this component.

 

cc: @hemalatha  @amanath_ullah  @mukeshyadav_ 

Thanks in advance.

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by pulkitvashisth

Hi @pulkitvashisth 

 

One more query. 

Which method calls the method: populate of AbstractProductRetriever.java for the first time, during the page load:
http://localhost:4502/content/venia/us/en/products/product-page.html/venia-tops/venia-sweaters/carina-cardigan.html

In debug mode, I came to know that Sling filter: com.adobe.cq.commerce.core.components.internal.servlets.CatalogPageNotFoundFilter.java
calls populate method as mentioned below:

 

if (siteStructure.isProductPage(currentPage)) { removeSlingScriptHelperFromBindings = addSlingScriptHelperIfNeeded(slingRequest, slingResponse); Product product = commerceModelFinder.findProductComponentModel(slingRequest, currentPage.getContentResource()); if (product != null && !product.getFound()) { slingResponse.sendError(HttpServletResponse.SC_NOT_FOUND, "Product not found"); return; } }

 

But according to me, at the end of init method of com.adobe.cq.commerce.core.components.internal.models.v3.product.java
populate() method has to be called. Since, in this initModel method calls: super.initModel();
Then, this method sets the productRetriever.extendProductQueryWith.

So, I am bit consfused with: for the first time, during the page load(above mentioned URL), which method calls the populate method?


Hi @mahesh_gunaje 
Firstly 

com.adobe.cq.commerce.core.components.internal.servlets.
SpecificPageFilterFactory
Filter gets triggered then the 
com.adobe.cq.commerce.core.components.internal.servlets.
CatalogPageNotFoundFilter
triggers.
Which internally calls the populate method on the class com.adobe.cq.commerce.core.components.internal.models.v1.product.ProductImpl object.

However the Graphql request goes mutiple times to the GraphqlClient
It serves request from localCahe and does not exectue pre-executed queries all over again.

You can checkout code for the same in the executeCached method
com.adobe.cq.commerce.core.components.internal.client.
MagentoGraphqlClientImpl

 

private GraphqlResponse<Query, Error> executeCached(String query, RequestOptions options) { try { if (localResponseCache != null && localResponseCache.containsKey(query)) { return localResponseCache.get(query); } GraphqlRequest request = new GraphqlRequest(query); GraphqlResponse<Query, Error> response = graphqlClient.execute(request, Query.class, Error.class, options); if (localResponseCache != null) { localResponseCache.put(query, response); } return response; } catch (RuntimeException ex) { LOGGER.error("Failed to execute query: {}", query, ex); return newErrorResponse(ex); } }

Let me know if this was your query.


 

1 reply

pulkitvashisth
Community Advisor
Community Advisor
August 12, 2024

Hi @mahesh_gunaje 
You are correct,
Inside com.adobe.cq.commerce.core.components.models.retriever.AbstractProductRetriever
The populate() method is used to fetch product info using graphql query.
The flow is ::
All the getter methods of 

com.adobe.cq.commerce.core.components.internal.models.v1.product.
ProductImpl
call the method 
productRetriever.fetchProduct() which returns Product Object
Inside this method 

 

 

public ProductInterface fetchProduct() { if (this.product == null) { populate(); } return this.product.orElse(null); }​

 

 

We have the logic to call populate() method, if the product is not already fetched using graphql query.

Let me know if you are looking for anything else or a solution around this.

Level 7
August 12, 2024

Hi @pulkitvashisth 

1:So, if we call fetchProduct() method multiple times, still graphQL query will be called only once. Correct me if I am wrong.

2: Whats is the type of product object. Since, ProductInterface is an interface only. is product is object of ConfigurableProduct class?

Level 7
August 12, 2024

One more observation from my side @pulkitvashisth 

 

com.adobe.cq.commerce.core.components.internal.models.v3.product.ProductImpl.java file


@PostConstruct
protected void initModel()

init method is callled several times if I load the page: http://localhost:4502/content/venia/us/en/products/product-page.html/venia-tops/venia-sweaters/carina-cardigan.html

I mean more than 10 times. Is this the normal behavior? I mean calling init method multiple times is the normal one?

 

Wanted to check, is there any personal blogs, Adobe articles related to implementation of AEM CIF framework?

 

Thanks in advance.