This article covers a Bloomreach Experience Manager version 12. There's an updated version available that covers our most recent release.

Mapping Model Bundles

Introduction

The Starter Store boot application can receive different types of data from external systems. Just think about products: a product list page powered by Bloomreach Experience Manager can potentially fetch products from different sources, such as e-commerce systems or Bloomreach Discovery, or even from different e-commerce systems at the same time (in the same web page!). 

One of the trickiest parts while fetching data from multiple sources is how to handle different data models. For example, a JSON object representing a product detail from a commerce backend could have a different structure than what comes from Bloomreach Discovery. The data needs to be mapped "internally" in the Starter Store application in order to properly use.

For this reason, a mapping strategy is needed to simplify developers' lives. The following two points represent main goals that should drive this strategy:

  1. Easy to use/configure: users don't need to change the application code base, this means no need to write Java code in case of changes to the data model. 
  2. Easy to maintain: changes to the mapping model shouldn't impact on existing implementations, like templates and more generally HST components. Moreover using different data sources in the same web page must be seamless. 

The Starter Store provides a solution based on resource bundles: the key/value map will contain all the technical details to extract the information needed. The following paragraphs describe more technical details.

Why a Mapping Model based on Resource Bundles?

Resource bundles are basically a set of key-value pairs. Those documents are mainly used to define generic values (perhaps in different languages) to be "dynamically" used in templates: more specifically, templates can use one or more bundle keys and during the rendering phase those keys are converted to their corresponding values. One of the main advantages of using resource bundles is that any change to those documents will reflect automatically and immediately in the web pages, without the need for code changes and/or redeployment.

Now let's see how those mapping bundles can be used in a Starter Store page. As an example, take a product list page: it basically consists of a list of products, each one containing at least a title, short description, and a thumbnail image. When the page is loaded, behind the scenes BRIEF is fetching all this product information: this means that all the related objects (like JSON or XML objects) are ready to be processed - mainly "mapped" to internal objects - directly in the templates.

Now the question is, how those different data representations can be handled in order to be seamlessly displayed? The idea in this process:

  • Each external data (e.g product detail) is fetched via BRIEF using a Commerce Connector.
  • Each Commerce Connector is "associated" to a Mapping Model Bundle.
  • Each Mapping Model Bundle defines a set of key/value pairs describing the object structure of the external data (like products list, product details, products category etc.) more specifically
    • key is a generic name used internally (by templates, components, etc.),
    • value defines the object path of a specific property.

So the resource bundle enables an easy way to define how to map the required properties to those in the external data structure.

As an example, suppose you need to display the title of a product in a product detail page. Then the process looks like this:

  • BRIEF will fetch the JSON object representing the product.
  • This JSON object will be part of the HST request attributes.
  • The template can access the title field in the JSON object by using the information specified in the mapping model bundle document .

How to define a Mapping Model using Resource Bundles?

The Mapping Model Bundle is a resource bundle document defined in the administration/mappings folder. The first thing to do is to create a new resource bundle there. As explained in the previous paragraph, this resource bundle will mainly contain the logic needed to "read" external data; but it can also contain standard resource bundle values (normal strings) that can be used in your templates.

The id field is the most important in this document: it should be of the form "starterstore.mapping.<connector_name>". The "connector_name" is the value of the Connector ID defined in your connector set document. There is a one to one relation between a connector and a mapping bundle: at the moment this relation is realized by name. Both the fields must share exactly the same name.

How to use a Mapping Model Bundle?

Every interaction with external systems involves a REST call retrieving the data (e.g. product detail). While fetching the data, the Starter Store implementation is aware of the connector that needs to be used. Once the request has been completed, the HST request object will be populated with two new  variables:

  1. result containing the object retrieved from the external service,
  2. mappingResourceBundle containing the mapping model bundle.

This mean that you can refer to those variables from within your Freemarker/JSP templates.

Moreover, the Starter Store boot application provides a set of template utilities (only for Freemarker in the initial release of the Starter Store): those files - mainly containing macros and functions - can be used directly in your customization. As an example, suppose you are working on the product detail page. You have a product-detail.ftl template which should render the product name, maybe at the top of your page. The following snippet represent a possible solution:

<#import "starterstore-helper.ftl" as helper>
...
<h1> ${helper.resolveProperty(result, "product.name", mappingResourceBundle)} </h1>
...

The property product.name is a key stored in the mapping bundle: the related value contains the path of the product name property part within the result object. 

It's worth mentioning that if you have a look at the implementation of the resolveProperty method, it's basically using all the utility methods provided by the CRISP implementation to retrieve the object values.

Can I still use POJO mapping based approach?

Yes, the Starter Store is actually using this solution as well: you can have a look at the POJO classes defined for users management (user detail, address etc.). 

Did you find this page helpful?
How could this documentation serve you better?
On this page
    Did you find this page helpful?
    How could this documentation serve you better?