Natively Composable Storefront / SAP Commerce Cloud doesn't support dynamic configuration. The only exception is regarding OCC EndPoint : OCC_BACKEND_BASE_URL_VALUE
And it is well known issue in Spartacus : https://github.com/SAP/spartacus/issues/5772
This article will explain how we can easily extend SAP Commerce Cloud and Composable Storefront to fill this gap. As example, we will use SAP CDC integration.
First thing is to extend OCC API BaseSite to enrich output with additional settings: occ/v2/basesites?fields=BASIC / BaseSitesController.getBaseSites()
For that, you need to create two custom extensions one for the core and for occ
In custom core extensions, you need to extend BaseSite item to record CDC settings (*items.xml)
<itemtype code="BaseSite" autocreate="false" generate="false">
<attributes>
<attribute type="java.lang.String" qualifier="cdcJavascriptUrl">
<persistence type="property" />
<modifiers optional="false" />
<description>CDC EndPoint with API Key</description>
</attribute>
<attribute type="int" qualifier="cdcSessionExpiration">
<persistence type="property" />
<modifiers optional="false" />
<description>CDC session expiration time in seconds</description>
</attribute>
</attributes>
</itemtype>Then Data and WsDTO beans need to be extended too (*beans.xml)
<bean class="de.hybris.platform.commercefacades.basesite.data.BaseSiteData">
<property name="cdcJavascriptUrl" type="String"/>
<property name="cdcSessionExpiration" type="Integer"/>
</bean>
<bean class="de.hybris.platform.commercewebservicescommons.dto.basesite.BaseSiteWsDTO">
<property name="cdcJavascriptUrl" type="java.lang.String">
<description>Indicates CDC EndPoint with API Key</description>
</property>
<property name="cdcSessionExpiration" type="java.lang.Integer">
<description>Indicates CDC Session Expiration time</description>
</property>
</bean>A new Populator should be introduced to add new settings in Data object (*spring.xml)
<bean id="cdcBaseSitePopulator" class="com.basesite.populator.CDCBaseSitePopulator"></bean>
<bean parent="modifyPopulatorList">
<property name="list" ref="baseSiteConverter" />
<property name="add" ref="cdcBaseSitePopulator" />
</bean>Popular implementation should look like to this
public class CDCBaseSitePopulator implements Populator<BaseSiteModel, BaseSiteData> {
@Override
public void populate(final BaseSiteModel source, final BaseSiteData target) throws ConversionException {
target.setCdcJavascriptUrl(source.getCdcJavascriptUrl());
target.setCdcSessionExpiration(source.getCdcSessionExpiration());
}
}To influence correctly Spring configuration, custom core must depend on commercefacades extension (extensioninfo.xml)
<requires-extension name="commercefacades"/>
OCC extension should be created according official documentation. The purpose is to extend WsDTO mapping for including additional CDC settings.
In /occ/v2/*occ/web/spring/*-web-spring.xml file, you can declare this following additional attributes
<!-- It extends baseSiteWsDTOFieldSetLevelMapping bean from commercewebservices -->
<bean parent="fieldSetLevelMapping" id="cdcSiteWsDTOFieldSetLevelMapping">
<property name="dtoClass" value="de.hybris.platform.commercewebservicescommons.dto.basesite.BaseSiteWsDTO"/>
<property name="levelMapping">
<map merge="true">
<entry key="BASIC"
value="cdcJavascriptUrl,cdcSessionExpiration"/>
</map>
</property>
</bean>After this customisation, you can compile and startup SAP Commerce Cloud. Then, you should connect to BackOffice for setting up the CDC settings in WCMS
Following that, you should be able to see the result by call OCC API BaseSite : https://localhost:9002/occ/v2/basesites?fields=BASIC
...
<baseSites>
<cdcJavascriptUrl>JS_SDK_URL_PLACEHOLDER_ELEC</cdcJavascriptUrl>
<cdcSessionExpiration>3600</cdcSessionExpiration>
<channel>B2C</channel>
<isolated>false</isolated>
<name>Spartacus Electronics Site</name>
<uid>electronics-spa</uid>
</baseSites>
</baseSiteList>
In client side, several things must be customised :
Type augmentation is clearly documented over here : https://sap.github.io/spartacus-docs/type-augmentation/
CDC dynamic loading can be executed by overriding static CdcConfig through Angular provider
Let first create a new module cdc.feature.module.ts that will inject CDC dynamic loading class
@NgModule({
declarations: [],
imports: [CdcRootModule],
providers: [
{
provide: CdcConfig,
useClass: DynamicCdcConfig
},
provideConfig({
featureModules: {
[CDC_FEATURE]: {
module: () => import('@spartacus/cdc').then((m) => m.CdcModule),
},
},
})
],
})
export class CdcFeatureModule {}DynamicCdcConfig class should look like this
import { BaseSiteService } from "@spartacus/core";
declare module '@spartacus/core' {
interface BaseSite {
cdcJavascriptUrl?: string,
cdcSessionExpiration?: number
}
}
@Injectable()
export class DynamicCdcConfig extends CdcConfig {
constructor(protected baseSiteService: BaseSiteService) {
super();
this.baseSiteService
.getActive()
.subscribe((currentBasesite) => (
this.baseSiteService.get(currentBasesite).subscribe((value) => (
this.cdc = [
{
baseSite: currentBasesite,
javascriptUrl: value?.cdcJavascriptUrl as string,
sessionExpiration: value?.cdcSessionExpiration as number,
}
]
))
));
}
}Then new module must be imported in app.module.ts to be loaded at startup
@NgModule({
declarations: [
AppComponent,
StaticPageComponent
],
imports: [
BrowserModule,
StoreModule.forRoot({}),
AppRoutingModule,
EffectsModule.forRoot([]),
SpartacusModule,
CdcFeatureModule
],
providers: [provideHttpClient(withFetch(), withInterceptorsFromDi()),],
bootstrap: [AppComponent]
})
export class AppModule {}As we saw, specific configuration by environment can be easily implemented in Composable Storefront. But If you need more support, please don't hesitate to contact SAP Expert Services.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
| User | Count |
|---|---|
| 10 | |
| 3 | |
| 2 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 |