Front-end development design
Front-end architectures
The Norce-based commerce application consists of a back-end layer, which interacts with Norce Commerce Services, and one or more front-end layers. These front-end layers can be hosted either on a web browser or on a client device or computer, based on the customer's specific requirements. It's worth noting that the front-end layer cannot directly call the Norce Commerce Services; instead, it relies on the back-end layer to do so. There are two main methods for hosting the back-end layer of the site.
CMS hosted back-end
In case the application requires a content management system that can accommodate custom components for API calls, the architecture may look like this:
The content management system (CMS) hosts customized server-side components that are in charge of retrieving and caching both data and metadata from the Norce Commerce Services. This architecture is frequently utilized in CMS-based solutions such as Optimizely, Umbraco, Sitevision, Sitecore, and various others.
Self-hosted back-end
When a CMS is not needed or an alternative "headless" CMS is used, Solution Partners can choose their technology and platform options freely because the backend layer is hosted independently.
This type of architecture is common in "headless" CMS solutions, such as Contentful or Prismic, among others.
Responsibilities of the back-end
- Interaction with the UI
Fetching data from services based on the actions of the user. - Mapping entities
The data entities provided by the Norce Commerce Services contain a lot of information, whereas the front-end usually requires only a small subset. - Business logic for presentation
Typically, the UI requires additional business logic to the data, such as converting "out of stock" from different warehouses to an availability message. - Consolidate data from different systems
In many cases there are multiple sources of data aside from Norce's, which may include a CMS, a search service, etc. The backend layer is responsible to consolidate all this to a client-specific data model. - Client specific business logic
Occasionally, it is necessary to override or extend the business logic in Norce.
Configurations
Content Delivery Network (CDN)
The Norce Commerce Services sends images and other blobs as keys (GUIDs). Together with a configured URL to the client's designated CDN, these keys provide links to the respective images and blobs.
The URL looks like this:
http://[client-specific-CDN]/[ImageKey]
The Norce image server utilizes Image Resizer components to resize images, and all provided parameters can be utilized to achieve the desired format. For instance, to obtain an image with a fixed width of 100 pixels, you can use:
http://[client-specific-CDN]/[ImageKey]?w=100
Further information regarding image functionality can be found here: Image Scaling and CDN.
OAuth2 authentication
Whenever a request is made to Norce, the back-end is required to determine which application to call as. This is accomplished by passing in the ApplicationId
as an HTTP Header. If this ID is not included, a 500 error will be returned.
Read more about authentication here: OAuth2 access.
Cache retention
A valuable suggestion is to cache data as much as possible. Despite Norce Commerce Services's rapid performance, in a service-oriented architecture, data should be cached whenever possible. Organize Norce's data into various groups with different retention periods and create a caching solution based on these groups. While the classification of data into different groups is usually client-specific, here is an example:
Group | Data | Retention |
---|---|---|
Long cache | Application configuration (default info, etc), Master lists (vat rates, countries, etc) | 24h |
Medium cache | Product base information, Product relations, Customer information, etc. | 1h |
Short cache | Basket, Prices, Availability | 5m |
Development patterns
Fetch data with batching and caching
When fetching data for a particular UI view, it's often a common practice to perform asynchronous requests and batch multiple requests to the Norce Commerce Services at once, after checking the local cache. Below is an example of the back-end fetching product information to be displayed on a product page.
- The user asks for a specific product.
- The back-end first checks its cache to see if it already has the required data to return.
- If there is no cached data, the back-end initiates several requests to the Norce Commerce Services in parallel, based on the specific view of the product. In this case, three data requests are made:
GetProduct
,ListProductRelations
, andListPromotions
. - The data from these three requests are returned independently by the Norce Commerce Services. As soon as the data starts to come back, the backend applies logic and mapping to the data and returns the result to the frontend.
- The frontend layer receives the result from the backend and starts rendering the view.
- The backend saved data to its local cache if needed.
To identify entities or handle input parameters for searches, Norce Commerce Services utilizes "IDs" which are often specific to a particular environment. For instance, the ProductId
for a T-shirt is not the same in Prod and Lab environments, and the same applies to other identifiers such as ParametricId
, SupplierId
, CategoryId
, PriceListId
, and so on.
You need to lookup entities dynamically to get the correct ID in your applications.
Update data
The API might update your cart data while you're working with its basket and checkout process. To make sure you have the correct, latest changes you should always use the returned basket from the latest method call. An example:
- A user looks at a product and clicks "add to basket".
- The action is sent to the backend, where a call to Norce Commerce Services is triggered.
- In the Norce Commerce Services, the method
InsertBasketItem
is called that takesbasketId
(not the whole basket), aBasketItem
, acreatedBy
account id, and other optional parameters as input and returns a newBasket
. - This newly returned basket must replace the old one in the frontend view as well as in caches.
- It is worth emphasizing that a seemingly minor modification to an entity (such as a Basket) can have a significant impact on the entity as a whole. For instance, if a product is added to the basket and there are promotions applicable to that product, various effects may be triggered, resulting in changes to the basket's contents or total amount, among other things.
The AccountId parameter is a valuable addition to all update methods in Norce Commerce as it enhances traceability. When a user is logged in, it is recommended to include their account Id as the parameter. If the user is not logged in, you should use 1 as the default value for this parameter.
Keeping a context
The Norce Commerce Services is designed to be stateless, which means that the server does not retain any information between API calls. As a result, all the necessary information must be included in each call to the API in order to obtain the desired response. This also means that the session in the backend application must maintain the entire session context. For instance, to display and list products, method calls such as GetProduct
or ListProducts
are necessary. While many of the input values for these calls remain constant, they should still be managed by the session to ensure that the result is based on the same context.
The Product example
List of parameters are not complete
method input | Description | Action | ListProduct2 | ListProductFilters2 | ListProductRelations | GetProduct |
---|---|---|---|---|---|---|
productId | Identifier of the product | not in context | - | - | Required. The product to find relations to | Required. pinpoints the specific product to fetch |
searchString | filtering the list of products | could either be kept in context, or be the result from a search input. | from context or from search | from context or from search | - | - |
storeSeed | Shows additional availability from the stores on the product | keep in context, used in most product calls | from context | from context | from context | from context |
priceListSeed | Shows additional product assortments and prices if exists. | keep in context, used in most product calls | from context | from context | from context | from context |
cultureCode | Shows specific language content instead of default on application | keep in context, used in most product calls | from context | from context | from context | from context |
Persistence
Determining what information should be stored in cookies or other storage mechanisms should be based on the context of the application.
For instance, in the given example, only the IDs (not the entire objects) are stored, and the objects are then loaded from these IDs into the cache (as discussed in the section on caching). The specific details of what should be persisted and for how long may vary depending on the particular use case.
The following image depicts an example of Norce [Storm]'s default configuration for the old client library in .net.
here is an example:
Value | Description | Scope |
---|---|---|
priceListSeed | Additional price lists other than the public. These are VIP or Loyalty club price lists | Stored during session |
accountId | Identifier of the know visitor to the site | Stored in persisted cookie |
customerId | Identifier of the customer, this is usually the customer associated with the account, but sometimes not | Stored in persisted cookie |
basketId | Identifier of the active basket | Stored in persisted cookie |
cultulureCode | Chosen language | Stored in persisted cookie |
storeId (alt 1) | Chosen physical store, or | Stored in persisted cookie |
storeId (alt 2) | Another scenario: Automatically resolved nearest physical store | Stored during session |
Tips and common practices
Using preloadings of the CDN
Avoid image cache problems by using preloadings to the CDN.
Trying to load all images from any image server at the time of a launch can cause performance issues. To avoid this problem, it is suggested to preload product images, especially for popular products, so that they are cached and ready to go on the CDN. This way, the launch will be fast and stable.
Resources and examples
Postman
There is a lot of good examples in the postman collection here.
The Sample storefront on GitHub is a good place to see a functional storefront design.