architecture

E-commerce Architecture in Fashion Industry

Fashion e-commerce across multiple countries means coordinating local prices, product content and fulfilment across web and mobile. This article explores an AWS architecture that connects the store to existing PIM and ERP systems and captures customer journeys without slowing the shopping experience.

Bartłomiej KotarskiBartłomiej Kotarski8 min read

Selling fashion across several countries means more than translating a storefront. Prices, taxes, promotions and delivery options vary by market, while customers expect a seamless experience across the web and mobile apps. Seasonal peaks add another challenge: the platform must stay fast when traffic rises sharply.

This article examines an architecture for a fashion retailer operating across five European markets, with a shared backend for web and mobile, product data managed in a PIM, and analytics to understand customer journeys. Read on to see how the right mix of edge delivery, a shared BFF and asynchronous integrations can support a faster, more consistent shopping experience.

Context

The client is an apparel brand selling online directly to consumers in five countries: France, Spain, Poland, Germany and Austria. Each market has its own language, currency, VAT rates, payment and delivery methods and local promotions. Traffic is high and seasonal: about 5 million visits per month, with peaks during sales periods when traffic multiplies within hours.

The product catalogue is managed in an external PIM by product managers from around the world. The ERP is responsible for stock levels, base prices and order fulfilment. Product images, critical for conversion in fashion, are served through a CDN. The company wants to understand user journeys (user flow) to optimise conversion.

Shoppers use many devices: desktop browser, mobile browser and native iOS and Android apps. The mobile app is a client requirement, not an option: it is to be a fully fledged sales channel with the same catalogue, cart and user account as the web. Each channel has different needs for data shape, response size and caching. For that reason the web frontend is built in Next.js (SSR/ISR for SEO and fast first render of category and product pages), and between the clients and the backend stands a single shared BFF (Backend For Frontend) in Nest.js, serving both web and mobile apps. The BFF aggregates calls to the commerce engine, PIM and ERP, tailors the response to the channel, and takes over caching and session handling.

Unlike banking, here the architecture is shaped by scale, performance and multi-market operation, not regulation:

  • high and variable traffic volume, requiring aggressive CDN caching and horizontal scaling;
  • five markets with separate localisation of content, prices, taxes, payments and deliveries;
  • many channels (web, iOS, Android) with one backend, including the required mobile app;
  • catalogue and media managed outside the store (PIM, DAM/CDN), synchronised into the commerce engine;
  • integration with the existing ERP as the source of truth for stock and orders;
  • user journey analytics without degrading site performance.

Existing systems: PIM, ERP.

Fashion Store: system context

A B2C store in five countries, running on AWS. PIM and ERP remain the source of truth for products, stock and orders.

Diagram C1 – System Context: Fashion Store

Figure 1. Diagram C1 – System Context: Fashion Store

Fashion Store: containers on AWS

One BFF for web and mobile. PIM and ERP are synchronised in the background via SNS + SQS.

Diagram C2 – Container: Fashion Store on AWS

Figure 2. Diagram C2 – Container: Fashion Store on AWS

Multi-market

One domain and one store installation serve all five markets; market selection happens at the network edge. Based on IP geolocation (the CloudFront-Viewer-Country header), CloudFront redirects the first visit to a locale-prefixed path (e.g. /pl-pl/, /de-at/) and passes the country to the Next.js Storefront, which renders the page in the right language and sends the market and language to the BFF in the X-Market and X-Locale headers. Based on these, the BFF fetches from the commerce engine the prices, VAT, availability and payment methods valid for that country, plus the marketing content for that market. The rendered HTML is cached on the CDN per locale, so subsequent visits from the same country hit the edge cache without backend calls.

A manual market choice is stored in a cookie and takes precedence over geolocation; countries outside the five markets land on /en/ with a market selector. The mobile app does not use redirects: the market chosen at first launch is sent in the X-Market header through the same CloudFront and WAF to the BFF.

Market routing via CloudFront geolocation

Five markets: FR, ES, PL, DE, AT. Geolocation picks only the first market; after that the URL path decides content, prices and cache key.

Market routing via CloudFront geolocation

Figure 3. Market routing via CloudFront geolocation

BFF (Backend For Frontend)

BFF is a pattern in which a dedicated API layer sits between the clients and the backend services, designed around the needs of the frontend rather than the structure of the domain. Instead of forcing the Storefront and the mobile app to call the commerce engine, search, CMS and Cognito separately and assemble the response on the client, the BFF makes those calls itself, aggregates the results and returns one view model tailored to the screen, e.g. a product page with the price in the market's currency, availability, images and marketing content in a single request.

In this application the BFF serves three goals. First, multi-channel: web and mobile get the same contract, but mobile can receive a lighter response without the fields needed only for SSR. Second, multi-market: the X-Locale header is interpreted in one place, and the logic for choosing the price list, VAT, payments and language is not duplicated in every client. Third, performance and resilience: the BFF keeps a response cache in Redis, limits the number of backend calls at 5 million visits per month, and isolates the frontends from changes in the commerce engine or PIM, because an integration change is a change in the BFF, not in a mobile app waiting for app store review.

The fourth goal is security. The BFF is the only publicly exposed API, so the commerce engine, search, PIM and ERP are not reachable from the internet, and their keys and addresses never end up in the browser or the mobile app bundle. The BFF verifies the Cognito token on every request and only then calls the backend with its own service credentials, so the frontend never holds permissions broader than the user's session. For web the BFF keeps the session in an httpOnly cookie with the Secure and SameSite flags instead of a token in localStorage, which limits token theft via XSS; for mobile it handles the refresh token and its rotation. Additionally the BFF enforces rate limiting per user and per IP, validates input, filters response fields down to those the screen needs so internal data does not leak, and logs requests with a correlation identifier for audit and debugging.

BFF as a stable contract

Frontends and backend services can be replaced independently. Only the BFF knows both sides, and the /v1 contract stays the same.

Diagram: BFF as a stable contract for replaceable frontends

Figure 4. Diagram: BFF as a stable contract for replaceable frontends

User traffic analytics

User journeys are tracked on the client side by a lightweight event SDK (web in the Storefront, native in the mobile app), which sends clickstream events (page_view, product_view, add_to_cart, checkout_step, purchase) with an anonymous session identifier, market and channel, after cookie consent is obtained in line with GDPR. Events flow through Amazon Kinesis Data Streams and Firehose into a data lake on S3 in Parquet format, where Glue catalogues the schema and Athena and QuickSight allow conversion funnels, path analysis and cross-market comparisons to be built without running a warehouse. A ready-made foundation is the Clickstream Analytics on AWS solution, which provides web/iOS/Android SDKs, an ingestion pipeline and built-in path, retention and funnel reports. The AI layer works on the same data: Amazon Q in QuickSight answers natural-language questions ("why did conversion in Austria drop this week"), a model on Amazon Bedrock summarises the most common paths and abandonment points and detects funnel anomalies, and Amazon Personalize learns from the same events and returns product recommendations to the BFF. Events contain a session identifier, not personal data, so analytics and AI run on anonymised data, and linking to the customer profile happens only on the commerce engine side with the user's consent.

Components:

  • Analytics SDK: web (Storefront) and mobile (iOS, Android), consent gate before sending
  • Amazon Kinesis Data Streams: real-time event ingestion
  • Amazon Kinesis Data Firehose: buffering, conversion to Parquet, writing to S3
  • Amazon S3: event data lake, partitioned by date and market
  • AWS Glue: schema catalogue, transformations
  • Amazon Athena: ad hoc SQL queries
  • Amazon QuickSight + Amazon Q: funnel and path dashboards, natural-language questions
  • Amazon Bedrock: path summarisation, funnel anomaly detection, insight generation
  • Amazon Personalize: product recommendations returned through the BFF
  • alternatively: Clickstream Analytics on AWS as a ready-made SDK + pipeline + reports package

Traffic analytics on AWS

Clients send anonymous events after consent. Raw events land in S3 as Parquet; SQL, dashboards and AI read the data from there.

Diagram: Traffic analytics on AWS

Figure 5. Diagram: Traffic analytics on AWS

Frequently asked questions

The store uses one domain and one installation for France, Spain, Poland, Germany and Austria. Market-specific content, prices, taxes, payment methods and delivery options are selected based on the locale and market sent to the BFF.

A shared Nest.js BFF provides a common API for the Next.js storefront and native iOS and Android apps. It aggregates backend data and adapts responses to each channel’s needs.

The PIM remains the source of truth for product information. The ERP is responsible for stock levels, base prices and order fulfilment. PIM and ERP data are synchronised in the background using SNS and SQS.

CloudFront caches rendered pages at the edge, while the BFF uses Redis to cache responses and reduce calls to backend services. The architecture is designed to scale horizontally during traffic peaks.

The BFF is the only publicly exposed API. It verifies Cognito tokens, applies rate limits and input validation, and calls backend services using its own credentials. For web sessions, it uses an httpOnly cookie with Secure and SameSite flags.

Web and mobile SDKs send clickstream events after cookie consent. Events are processed through Kinesis and Firehose, stored in S3 as Parquet, and analysed using services such as Athena and QuickSight.

Analytics events use an anonymous session identifier and are sent only after consent. Linking events to a customer profile happens on the commerce engine side with the user's consent.

Filed underarchitecture