Broadleaf Microservices
  • v1.0.0-latest-prod

Facilitating Product Details Pages

Overview

Catalog Services provides an endpoint to facilitate building product details pages in as few requests to the Catalog APIs as possible. ProductDetailsEndpoint is the entry-point for requests, and ProductDetailsService is the place to start for customizing the response.

Tip
For minimizing calls including to other microservice APIs such as Pricing Services, consider using the CatalogBrowse microservice, which comes with an integration to the pricing engine already for category browse, product details, and search results pages.

ProductDetailsEndpoint

The ProductDetailsEndpoint provides access to one or more Products and all data relevant to a product details or list page. It will ensure that its hierarchy of related entities, like IncludedProducts, ProductOptions, and Variants, are properly hydrated and priced so as to minimize the complexity that the caller must handle. In particular, since SpecificItemChoice and IncludedProduct entities also have an underlying Product or Variant, the inherited price will be copied up from those underlying entities onto the SpecificItemChoice or IncludedProduct so that the caller does not need to determine them itself.

Tip
See the OpenAPI spec for the product details endpoint.

Request Details

The endpoint takes the following parameters to determine which products to retrieve:
  • productUris: One or more URIs that map to specific products. This is used if productIds are not provided and is the typical way products are identified by a commerce-facing app since the URL that a user has navigated to is available while the specific IDs of the products are not.

  • productIds: The specific IDs of the products to retrieve

Any other parameters are automatically placed in an attributes map on the ProductDetailsRequest DTO and be referenced in the business logic thereby.

Response Details

The following diagram covers the overall response DTOs. Most of these DTOs are simply augmented versions of basic Catalog entities and shared fields were omitted in favor of focusing on what’s added.

Product Details DTO Diagram
Figure 1. Response Details Diagram

ProductDetailsList

The endpoint responds with a ProductDetailsList. This includes the list of requested ProductDetails as well as any requested IDs or URIs for which no product was found.

Fields included in response:
  • productDetails: List of ProductDetails DTOs

  • productIdsForMissingEntities: If productIds were provided in the request, this is the set of those that didn’t match a product

  • productUrisForMissingEntities If productUris were provided in the request, this is the set of those that didn’t match a product

ProductDetails

ProductDetails represents an augmented version of a Product that includes all the disparate relationships it has consolidated into one object. It includes all of the fields of the base product except the pricing ones which are consolidated into priceInfo for consistency in how the frontend handles pricing whether it’s from Catalog Services or Pricing Services (which has more advanced pricing abilities). It additionally includes:

  • advancedTags: All of the product’s related ProductTags.

  • assets: All of the product’s assets' metadata including their:

    • type: The asset type: IMAGE, VIDEO, PDF, etc.

    • altText: Corresponds to the HTML alt attribute on an <img> tag.

    • title: Corresponds to the HTML title attribute on an <img> tag.

    • contentUrl: The full URL used to resolve the actual asset content such as a CDN path for an image. Included instead of the base url since this is what the caller will actually use to resolve an asset.

    • embedCode: HTML to embed on a frontend

    • tags: Additional, descriptive or identifying text that can be used to associate an image with a specific Variant or ProductOption value, for instance

    • See ProductAsset javadocs for the full details.

  • breadcrumbs: List of navigational breadcrumbs based on the product’s request context or category hierarchy

  • includedProducts: Hydrated list of additional, included items (like fixed quantity add-ons) with their own consolidated data

  • options: List of ProductOptions with their item or attribute choices hydrated with the appropriate product or variant details. Most of the complexity in retrieving products comes from ensuring that these options are as complete as possible for a frontend to display and allow for configuration by a customer without additional backend calls or complex logic to build the hierarchies.

  • parentCategories: Simplified references to the categories that contain the requested product Includes:

    • id: ID of the category

    • name: Name or label of the category

    • url: URL for displaying details of the category in a commerce-facing app

  • priceInfo: Pricing information for a target (e.g., Product or Variant), providing the target, best price, and some details about the other candidate prices. This is intended to make it easier for the caller to find the right price to display. If the best overall price is a 'sale price', then the details could contain the best standard/retail price if there was one.

  • promotionalProducts: Lists of the various kinds of promotional products such as cross-sale and up-sale mapped by their type

  • variants: List of all of a product’s Variants

  • vendorRef: If relevant, the ID or reference to a Vendor.

Tip
See the ProductDetails javadoc for further details.

ProductDetailsService

This service is responsible for retrieving ProductDetails for ProductDetailsRequests. It is responsible for building the augmented Product and its hierarchy. By default, it defers the meat of the work to the ProductDetailsContributors, ProductDetailsContextContributors, and ProductDetailsContextConsolidators.

  1. The process starts by building a ProductDetailsContext. This facilitates gathering all of the related catalog entities to the requested product all at once to allow fewer calls to the database throughout the process. This is done by:

    1. Gathering all of the context info using the ProductDetailsContextContributors.

    2. Then, consolidating it onto the related entities such as adding ProductAssets to the related Products using the ProductDetailsContextConsolidators.

  2. Once the context is setup, the ProductDetailsContributors are invoked to actually populate the gathered data onto the ProductDetails DTO.

ProductDetailsContext

Information required to build ProductDetails for a commerce-facing product details page. This contains important context information for determining which product to gather details for and, potentially, the extent of the details. Prior to building the details themselves, this context is constructed to store all of the catalog entities related to the requested product to allow for as few calls to the database as possible. After this, the data is organized hierarchically as appropriate without needing additional database requests.

ProductDetailsContextContributors

These services are responsible for contributing a specific subset of information to a ProductDetailsContext based on a ProductDetailsRequest such as the related category, product, and variants in order to retrieve all related entities in bulk operations rather than piece-meal for performance reasons. It is desirable for implementations of this class to be as narrow as possible in the breadth of their contributions to improve extensibility, re-usability, testability, and readability.

Important
Contributors should handle all the database queries necessary for gathering all the related entities while consolidation (such as merging product assets onto related products) should be handled by ProductDetailsContextConsolidators as consolidators will run after all contributors.
The contributors provided out-of-box are, in order they are run:
  1. RelatedCategoriesProductContextContributor: Contributes all of the related Categories to the ProductDetailsContext.

    • This will look through all of the item choice ProductOptions and find all parent categories for the resolved Products.

    • Extend #contributeOtherCategoryIds to contribute other category IDs before fetching all of the related Category.

  2. RelatedPromoProductsProductContextContributor: Contributes all of the related PromotionalProducts to the ProductDetailsContext.

    • This will only look at the primary resolved product and not through it’s hierarchy for additional promotional products, e.g., an IncludedProduct’s promotional products are left out.

    • This should be run before RelatedProductsProductContextContributor to allow us to gather all the related promotional products at the same time as related products.

  3. RelatedProductsProductContextContributor: Contributes all of the related products and categories' products to the ProductDetailsContext.

    • This will look through all of the IncludedProducts and item choice ProductOptions. By default, this will not look deeper than the first level of item choices—that is to say, the item choices of item choices will be left out.

    • This should run after RelatedCategoriesProductContextContributor since we want to get all of the products for each of those categories at the same time as the rest of the related Products.

    • Extend #contributeOtherProductIds to contribute other product IDs before fetching all of the related products.

  4. RelatedProductTagsProductContextContributor: Contributes all of the related ProductTags

    • This will hydrate the AdvancedTags onto the ProductTags.

    • This also filters out automatically any inactive ProductTag or ProductTags related to inactive AdvancedTags.

  5. ItemChoiceHierarchyProductContextContributor: Contributes all the related products, related variants, related option templates and specific choice categories for the item choice hierarchy.

    • Affected by broadleaf.catalog.service.maxConfigurableProductDepth, which defines the depth to which the system will build out these item’s own hierarchies. That is to say, this controls whether an item choice’s product options and included products are also hydrated.

      • Default depth is 2, where 1 means no additional hydration is done.

  6. RelatedDataDrivenEnumsProductContextContributor: Contributes all of the related DataDrivenEnums to the ProductDetailsContext.

    • This includes brand, merchandising type, and target demographic of the resolved Products.

  7. RelatedVariantsProductContextContributor: Contributes all of the related Variants to the ProductDetailsContext.

    • This will look through all of the IncludedProducts, item choice ProductOptions, and related Products.

    • This should be run after RelatedProductsProductContextContributor to allow us to gather all the variants at once.

    • Extend #contributeOtherVariantIds to contribute other variant IDs before fetching all of the related variants.

  8. RelatedProductAssetsProductContextContributor: Contributes all of the related ProductAssets to the ProductDetailsContext.

    • This should be run after RelatedProductsProductContextContributor to allow us to gather all the assets at once.

ProductDetailsContextConsolidators

These services handle consolidating context information provided by ProductDetailsContextContributors as needed such as consolidating product assets onto the related products.

Important
ProductDetailsContextContributors should handle any necessary database queries to gather the related entities while contributors merge the data together before they are contributed to a ProductDetails.
The consolidators provided out-of-box are, in order they are run:
  1. RelatedOptionTemplatesProductContextConsolidator: Consolidates all of the related option templates onto products with options referencing those templates. It’s important that this happens before consolidating related products or variants since some of these are referenced from Option Templates.

  2. RelatedProductsProductContextConsolidator: Consolidates all of the context info for related products onto those products.

  3. RelatedVariantsProductContextConsolidator: Consolidates all of the context info for related variants onto those variants.

  4. RelatedPromotionalProductsProductContextConsolidator: Consolidates all of the context info for related promotional products onto those products.

  5. ItemChoiceCategoriesProductContextConsolidator: Consolidates of all the context info for item choice categories onto those categories.

ProductDetailsContributors

ProductDetailsContributors are responsible for contributing a specific subset of information to a ProductDetails based on a ProductDetailsContext such as contributing the related assets or contributing the pricing info. It is desirable for implementations of this class to be as narrow as possible in the breadth of their contributions to improve extensibility, re-usability, testability, and readability. This also provides a simple means of adding in additional augmentations to the ProductDetails response by registering a new contributor.

The contributors provided out-of-box are, in order they are run:
  1. ProductOptionsProductDetailsContributor: This contributor is responsible for all of a ProductDetails' ProductOptions.

  2. VariantsProductDetailsContributor: Contributor responsible for the ProductDetails' Variants.

  3. ProductAssetsProductDetailsContributor: Contributor responsible for the ProductDetails' Assets.

  4. IncludedProductsProductDetailsContributor: This contributor is responsible for all of a ProductDetails' IncludedProducts.

  5. PromotionalProductsProductDetailsContributor: Contributor responsible for the ProductDetails' PromotionalProducts.

  6. DataDrivenEnumsProductDetailsContributor: This contributor is responsible for ProductDetails' DataDrivenEnums.

  7. VendorRefProductDetailsContributor: This contributor is responsible for populating the vendorRef.

  8. AdvancedTagsProductDetailsContributor: This contributor is responsible for populating the advancedTags.

  9. PriceInfoProductDetailsContributor: This contributor is responsible for the ProductDetails' price info.

  10. CategoriesProductDetailsContributor: This contributor is responsible for the ProductDetails' parent Categories.

  11. BreadcrumbsProductDetailsContributor: This contributor is responsible for the ProductDetails' breadcrumbs.

  12. MinifyProductDetailsContributor: Strip out (or transform) information for a product details request before passing back to the caller.

    • This is useful for reducing the overall JSON footprint for the details, especially in the case of unused information.

    • This contributor should normally be last in the list.