Skip to content

Latest commit

 

History

History
256 lines (221 loc) · 13.2 KB

README-TECH.md

File metadata and controls

256 lines (221 loc) · 13.2 KB

EPiServer Commerce - VueStorefront integration demo

This is a demo implementation showing how to use EpiServer Commerce as a backend platform for Vue Storefront. This demo is based on the Episerver Commerce Quicksilver sample site. The main goal of this project is to provide a set of algorithms and data structures that will help with the integration of EPiServer Commerce and Vue StoreFront. Provided solution consists of two parts: ApiBridge and DataExporter.

  1. ApiBridge - implements web api required by VSF
  2. DataExporter - reading, converting and exporting data models from EpiServer to Elasticsearch (where it can be accessed by VSF)

Although the example implementation is based on Quicksilver, both ApiBridge and DataExporter have been developed with customization in mind.

Project setup

  1. Setup Quicksilver demo - Quicksilver project
  2. Setup VSF application - Windows Installation or Linux Installation

Changes introduced to Quicksilver demo

  1. EPiServer.Reference.Commerce.VsfIntegration project has been added. This project contains examples of custom model mappers (e.g. QuicksilverProductMapper) and service adapters (e.g. QuickSilverUserAdapter).
  2. EPiServer.Reference.Commerce.Site->Features->Product->Models has been moved to EPiServer.Reference.Commerce.Shared->Models->Products

How to run this demo

1. Configuration

1. vue-storefront local.config

An working example can be found HERE
List of customized properties with example values:

{
    "elasticsearch": {
      "index": "epi-catalog",
      ...
    },
    "cart": {
      "setCustomProductOptions": false,
      "setConfigurableProductOptions": false,
      "create_endpoint": "http://localhost:50244/vsbridge/Cart/create?token={{token}}",
      "updateitem_endpoint": "http://localhost:50244/vsbridge/Cart/update?token={{token}}&cartId={{cartId}}",
      "deleteitem_endpoint": "http://localhost:50244/vsbridge/Cart/delete?token={{token}}&cartId={{cartId}}",
      "pull_endpoint": "http://localhost:50244/vsbridge/Cart/pull?token={{token}}&cartId={{cartId}}",
      "totals_endpoint": "http://localhost:50244/vsbridge/Cart/totals?token={{token}}&cartId={{cartId}}",
      "paymentmethods_endpoint": "http://localhost:50244/vsbridge/Cart/payment-methods?token={{token}}&cartId={{cartId}}",
      "shippingmethods_endpoint": "http://localhost:50244/vsbridge/Cart/shipping-methods?token={{token}}&cartId={{cartId}}",
      "shippinginfo_endpoint": "http://localhost:50244/vsbridge/Cart/shipping-information?token={{token}}&cartId={{cartId}}",
      "collecttotals_endpoint": "http://localhost:50244/vsbridge/Cart/collect-totals?token={{token}}&cartId={{cartId}}",
      "deletecoupon_endpoint": "http://localhost:50244/vsbridge/Cart/delete-coupon?token={{token}}&cartId={{cartId}}",
      "applycoupon_endpoint": "http://localhost:50244/vsbridge/Cart/apply-coupon?token={{token}}&cartId={{cartId}}&coupon={{coupon}}",
      ...
    },
    "users": {
      "endpoint": "http://localhost:50244/vsbridge/user",
      "history_endpoint": "http://localhost:50244/vsbridge/user/order-history?token={{token}}",
      "resetPassword_endpoint": "http://localhost:50244/vsbridge/user/reset-password",
      "changePassword_endpoint": "http://localhost:50244/vsbridge/user/change-password?token={{token}}",
      "login_endpoint": "http://localhost:50244/vsbridge/user/login",
      "create_endpoint": "http://localhost:50244/vsbridge/user/create",
      "me_endpoint": "http://localhost:50244/vsbridge/user/me?token={{token}}",
      "refresh_endpoint": "http://localhost:50244/vsbridge/user/refresh",
      ...
    },
    "stock": {
      "endpoint": "http://localhost:50244/vsbridge/stock",
      ...
    },
    "images": {
      "useExactUrlsNoProxy": true,
      "baseUrl": "http://localhost:50244/vsbridge/image/",
      ...
    },
    ...
}

2. vue-storefront-api local.config

An working example file can be found HERE
List of customized properties with example values:

{
  "elasticsearch": {
    "indices": [ "epi-catalog" ],
    ...
  },
  ...
}

3. EPiServer.Reference.Commerce.Site - web.config

List of customized properties with example values:

<configuration>
    <configSections>
        ...
        <section name="vsf.export" type="EPiServer.Vsf.DataExport.Configuration.VsfExporterConfiguration, EPiServer.Vsf.DataExport"/>
        <section name="vsf.apiBridge" type="EPiServer.Vsf.ApiBridge.VsfApiBridgeConfiguration, EPiServer.Vsf.ApiBridge"/>
    </configSections>
    ...
    <vsf.export 
        elasticServerUrls="http://127.0.0.1:9200" 
        indexAliasName="epi-catalog" 
        bulkIndexBatchSize="100" />

    <vsf.apiBridge 
        auth.signingKey="alamakotaalamakotaalamakotaalamakota"
        auth.issuer="quicksilver_issuer"
        auth.audience="quicksilver_audience"
        auth.accessTokenExpiration="60" />

2. Data Export

Quicksilver to VSF export procedure.

  1. Before exporting make sure that:
    1.1 VSF (vsf and vsf-api) is up and running
    1.2 Quicksilver page is up and running
  2. Navigate to EPiServer CMS Admin panel -> Scheduled Jobs -> Export to Vue Storefront
  3. Start Manually

After the job has finished, refresh VSF application - all product should be visible.

Solution structure

Quicksilver example default projects:
EPiServer.Reference.Commerce.Site
EPiServer.Reference.Commerce.Shared
EPiServer.Reference.Commerce.Manager

Actual Demo projects:
EPiServer.Vsf.Core - set of core models and interfaces
EPiServer.Vsf.ApiBridge - implementation of VSF web api bridge
EPiServer.Vsf.DataExport - implementation of exporting and model mapping algorithms
EPiServer.Reference.Commerce.VsfIntegration - quick silver customization. This project contains examples of custom model mappers (e.g. FashionProductMapper) and service adapters (e.g. QuickSilverUserAdapter).

Todo/Known bugs

  1. RefreshTokenRepository - Currently there is only one class that implements IRefreshTokenRepository interface, and it is MemoryRefreshTokenRepository.
  2. StockAdapter - QuickSilverStockAdapter is not fully implemented. The returned VsfStockCheck object is in grate part mocked.
  3. Placing order after checkout process with account creation does not properly assing order (due to userId) not being sent.

EPiServer.Vsf.Core

This project provides a set of base classes and interfaces used in project EPiServer.Vsf.ApiBridge and EPiServer.Vsf.DataExport. The intent is that One can override whole logic with custom implementation.

Folders structure

.
+-- ApiBridge - interfaces and models related to VueStoreFront Api bridge.
|   +-- Adapter - adapter interfaces for managing users, cars and stock
|   +-- Endpoint - api bridge interfaces
|   +-- Model - models related to VueStoreFront Api bridge
|   |   +-- Authorization - related to authorization 
|   |   +-- Cart - related to carts 
|   |   +-- Stock - related to stock
|   |   +-- User - related to users
+-- Exporting - set of interfaces related to exporting 
+-- Mapping - set of interfaces related to exporting 

EPiServer.Vsf.ApiBridge

This project provides the implementation for VSF api bridge. VSF api description can be found HERE

Folders structure

.
+-- Authorization
|   +-- Claims
|   +-- Token
+-- Controllers
+-- Endpoints
+-- Utils

Authentication

JwtBearerAuthentication middleware is used with custom token provider (VsfJwtBearerTokenProvider).
VsfJwtBearerTokenProvider class is able to extract Jwt token not only from Authorization header, but also from query string.
JwtUserTokenProvider class is responsible for generating access and refresh tokens.

More information about VSF authentication can be found HERE

Api status

POST /vsbridge/cart/create - implemented
GET /vsbridge/cart/pull - implemented
POST /vsbridge/cart/update - implemented
POST /vsbridge/cart/delete - implemented
POST /vsbridge/cart/apply-coupon - implemented (further testing needed)
POST /vsbridge/cart/delete-coupon - implemented (further testing needed)
GET /vsbridge/cart/coupon - implemented (further testing needed)
GET /vsbridge/cart/totals - implemented (further testing needed)
GET /vsbridge/cart/payment-methods - implemented (further testing needed)
POST /vsbridge/cart/shipping-methods - implemented (further testing needed)
POST /vsbridge/cart/shipping-information - implemented (further testing needed)
POST /vsbridge/cart/collect-totals - implemented (further testing needed)

POST /vsbridge/user/create - implemented
POST /vsbridge/user/login - implemented
POST /vsbridge/user/refresh - implemented
POST /vsbridge/user/resetPassword - implemented
POST /vsbridge/user/changePassword - implemented
GET /vsbridge/user/order-history - implemented (further testing needed)
GET /vsbridge/user/me - implemented
POST /vsbridge/user/me - implemented

GET /vsbridge/stock/check/:sku - partially implemented

POST /vsbridge/order/create - implemented (further testing needed)

EPiServer.Vsf.DataExport

This project provides support for exporting EPiServer Commerce models (mainly products, categories and variants) to Elasticsearch index, where it can consumed by VSF frontend app.

Note

VSF is using model structure similar to Magento2, and it is assumed that the reader is familiar with both models structures: EPiServer Commerce, Magent2 and he understands the differences between them.

Folders structure

.
+-- Attributes
+-- Configuration
+-- Exporting
+-- Mapping - set for models mappers (from EPiServer models to VSF)
+-- Model - set of models suited for indexing in elasticsearch 
+-- Utils
    +-- Epi

Important classes description

ContentExtractor - is responsible for extracting data (nodes and products) from EpiServer Commerce. ExtractedContentHandler implements logic for handling that data (e.g. mapping to VSF model, indexing in Elasticsearch)
IndexingService - implements logic for indexing data in Elasticsearch
AttributeMapper, CategoryBaseMapper, ProjectBaseMapper - logic for mapping EPiServer Commerce models to VSF
VsfBaseProduct - base VSF product model that should be customized. (see QuicksilverVsfProduct)
QuicksilverVsfProduct - includes Quicksilver products specific properties (e.g. ColorOptions and SizeOptions)
QuicksilverProductMapper - customized mapping for Quicksilver products
QuicksilverNodeMapper - customized mapping for quicksilver nodes

Other important classes

CategoryTreeBuilder - is a helper class for mapping EPiServer NodeContent structure to VSF Category model
ContentPropertyReader - helper class for reading EPiServer Variants properties marked with VsfOptionAttribute
VsfOptionAttribute - is used to mark Variants properties that should be automatically mapped to VSF attributes model. (see EPiServer.Reference.Commerce.Shared.Models.Products.FashionVariant)

EPiServer.Reference.Commerce.VsfIntegration

This project contains Quicksilver specific implementation (e.g. QuicksilverProductMapper, QuickSilverUserAdapter).

Important classes

InitializationModule - InitializationModule that will setup DI for this demo
VueStorefrontExportJob - EPiServer job that executes model exporting

EPiServer.Reference.Commerce.Site

VSF ApiBridge registration

In SiteInitialization.ConfigureContainer:

GlobalConfiguration.Configure(config =>
{
  config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.LocalOnly;
  config.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings();
  config.Formatters.XmlFormatter.UseXmlSerializer = true;
  config.DependencyResolver = new StructureMapResolver(context.StructureMap());
  config.MapHttpAttributeRoutes();

  //REGISTER VSF API
  config.RegisterVueStorefrontBridge();
});

VSF JwtBearerAuthentication registration

In Infrastructure.Owin.Startup.Configuration

//REGISTER VSF AUTH
app.RegisterVueStorefrontAuth(ConfigurationManager.GetSection("vsf.apiBridge") as VsfApiBridgeConfiguration);