Broadleaf Microservices
  • v1.0.0-latest-prod

Catalog Browse Release Notes for 2.2.0-GA

Tip
The 2.x versions are Spring Boot 3 compatible.

Important Updates

Spring Boot Upgrade

  • As of Broadleaf Release Train 2.3.0-GA, all microservices have been upgraded to support Spring Boot 3.3 & 3.5.

Requirements

  • JDK 17 is required for Broadleaf release trains 2.0.0-GA, and beyond.

New Features & Notable Changes

Add Ehcache and Caffeine cache support

  • Added support for Ehcache and Caffeine caches for dynamic customer segments.

  • For more information on configuring these caches, see the Caching Configuration guide.

  • Accept a new skipInventory parameter in /browse/products (aka /products/details) to skip inventory availability checks. Internally, the backend flow already supported honoring ProductDetailsRequest.skipInventory, but this setting was not exposed via the API.

  • Updated the pricing logic to use product’s default frequency when doing initial product pricing (e.g. PDP and PLP views) for products with recurring pricing

Feature: Added mechanism to filter out sensitive data from browse product payloads

See the CartOperation-counterpart of this mechanism in Cart Operation Services 2.3.0 Release Notes.

Introduced an OncePerRequest filter guarded by configured URIs patterns that will remove the baseCost property from the CatalogBrowse response payloads.

This mechanism can be configured by the following properties and is enabled by default (see CatalogBrowseSensitiveDataRemovalProperties):

broadleaf:
  catalogbrowse:
    sensitive-data-removal:
      enabled: true
      url-patterns:
        - /browse/*
        - /products/details
        - ... etc.
      fields-to-remove:
        - cost          # default
        - baseCost      # default

Feature: Variant Pricing Strategy

Important
Requires Catalog Services 2.3.0

Feature: Variant Pricing Strategy

Variant Pricing Strategy was introduced to the Product domain to assist users who price Variants based on the Product’s SKU rather than the Variants' own. By default, Broadleaf sends PriceableTargets to the Pricing Service for every Variant as well as the parent Product. In this case, the Product’s pricing (whether by SKU or pricing key) acts as the fallback if a Variant doesn’t have a price specified.

However, there are cases where users never specify variant-specific pricing, using other mechanisms to vary pricing such as the new Two-Tier pricing targeting Characteristic values. Consequently, performance can be improved by skipping sending the PriceableTargets for the Variants and instead only using the Product’s price. This is additionally useful in such cases when there are also a very large number of variants.

Therefore, a new field has been added to Product, variantPricingStrategy, to determine whether to price by the product only.

The supported values out-of-box:
  • PRODUCT: All the variants will always use product-level pricing, e.g., catalog’s product-level pricing, price data targeting pricing key, etc., useful to if variant-level pricing isn’t needed.

  • VARIANT: Variant-level pricing will take precedence, e.g., price data targeting variant SKU or pricing key. If variant-level pricing isn’t available, product-level pricing will still be used.

    • This is the previous behavior.

  • DEFAULT: Delegates to the system setting to determine whether Product or Variant pricing strategy should be used.

    • Set the system behavior with broadleaf.common.default-configurations.product.variant-pricing-strategy.

Improved support for AddOn pricing and the UX for its configuration

Important
Requires Catalog Services 2.3.0
  • Updated the pricing comparator to prioritize as follows:

    • VariantPricingOverride if it exists

    • PriceData targeting the add-on’s pricing key

    • Direct price set on the add-on

    • Underlying entity match (follows existing logic for priority (e.g. price data, price lists, direct pricing)

  • Removed logic that always builds priceableTarget for defaultProduct and defaultVariant when building for options

    • This target is redundant because we are already building the targets for all the specific choices, which the default product or variant is already in there too

  • Added logic to build the PriceableTargets for underlying product’s variants for specific item choices

  • Updated the ProductOptionsProductPriceableTargetsBuilder to return empty set of targets early if override price exist for the ItemChoice or SpecificItemChoice

    • No need to build and price the underlying products/variants if the ItemChoice or SpecificItemChoice already has an explicit price override

  • Added support for variant based products to be a product’s add-on

Inventory Availability Index

Introduced a new GET /inventory-availability-index/{productId} endpoint that returns basic variant information along with inventory availability information for a given product. This endpoint is intended to be used in commerce flows to retrieve inventory availability information for all variants of a product in a single request and replace hydrating full VariantDetails onto the ProductDetails. The index uses the variant option values as the keys to allow fast lookup in the frontend to be used alongside option selector components to hide/grey-out unavailable options and the add-to-cart button.

Example Payload
type InventoryAvailabilityIndex = {
  variants: {
    "gold:XL": {
      id: string;
      sku: string;
      optionValues: Record<string, string>;
      available: boolean;
    }
  }
}

Primary Use Case

Using this endpoint rather than hydrating the full variant details is particularly useful for products with large numbers (e.g., hundreds) of variants to improve performance and time to first paint. To maximize its effect, set default variant hydration behavior for product details in Catalog Service to NONE and have the frontend make a separate call to fetch the inventory availability index in asynchronously such as in a useEffect or server function. This allows the main content to load and be painted more quickly while the availability index is retrieved before the user can actually interact with the page.

Disable Variant Hydration for Product Details
broadleaf:
  catalog:
    product:
      details:
        variant-hydration-behavior: NONE

Other Implementation Details

  • Added new InventoryAvailabilityIndexService to orchestrate calls to the Catalog and Inventory providers to fetch lite variant and inventory availability information for all variants of a product.

  • Added a new LiteVariant DTO, which is a lightweight representation of a Variant.

  • Added new fetchLiteVariantsForProduct method to the ExternalCatalogProvider

  • Added new getInventoryAvailabilityForSkus method to the ExternalInventoryProvider

    • The default implementation builds a collection of SkuInventoryAvailabilityRequests and calls the bulk availability API in Inventory Services.

  • The map key for AvailabilityInfo#variants takes the variant option values and joins each value with a semicolon in alphabetical order by key. For example, given the following option values

    {
      "size": "XL",
      "color": "gold"
    }

    The key would be gold:XL. ** To modify this behavior, extend DefaultInventoryAvailabilityIndexService#buildOptionValuesKey

Bug Fixes

  • ExternalInventoryProvider.getInventorySummaries was previously making a request to inventory services even when there were no items to provide in the request payload (for example, all requested products had inventory check/reserve strategy settings set to NEVER). There is now a check in this flow to examine whether the requested item list is empty before proceeding to make a request to inventory services, reducing unnecessary system load.

  • Fixed an issue where the "Pay In Full" button appears twice for Products configured with recurring pricing and a default frequency that is not "One-Time" on the Product Details Page.

  • Fixed an issue where incorrect and redundant Purchasing Options are being displayed for Variant Products whose Base Price is different from the variant’s price.