Upload
nurun
View
796
Download
3
Embed Size (px)
DESCRIPTION
Last year, Nurun and Walmart Canada launched the first responsively designed enterprise e-commerce website created for a large Canadian retailer. Built on a new platform with the Play Framework, Scala and Akka at its core, this foundation has proven itself in terms of flexibility, developer productivity, performance and scalability. We’ll share some of the insights we’ve gained in creating a best of breed solution that scales to Walmart’s needs—now and into the future.
Citation preview
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Reactive Retail
Big Retail Goes Reactive at Walmart NOVEMBER 2014
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Introduction Walmart.ca re-architecture Move to Functional Programming Technical Tips & Features Experiences and Impressions Outlook Q&A
Agenda
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
About Nurun
12
Atlanta
Nancy
Shanghai
Quebec Turin
Montreal
Paris
Milan
Toronto
San Francisco
Chicoutimi
Madrid
1,200+ Employees
14 Years In Business
Retail
Automotive
Financial Services
Media & Entertainment
Fashion & Beauty
AREAS OF EXPERTISE
Utilities
Government
Telecommunications
Travel & Hospitality
Health & Pharma
3
We are a global design & technology consultancy with 12 offices worldwide.
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Introduction
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Introduction
TYPICAL LARGE ECOMMERCE ENVIRONMENTS
E-Commerce Platform
RDBMS
JSPs
Product content management
CDN
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Introduction
TYPICAL LARGE ECOMMERCE ENVIRONMENTS
E-Commerce Platform Search &
merchandizing
RDBMS
JSPs
Product content management
CDN
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Introduction
INCUMBENT PLATFORM
• ATG, Oracle • Fairly monolithic
• Rapidly evolving merchandising needs
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Introduction
INCUMBENT PLATFORM
• ATG, Oracle • Fairly monolithic
• Rapidly evolving merchandising needs
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Introduction
INCUMBENT PLATFORM
• ATG, Oracle • Fairly monolithic
• Rapidly evolving merchandising needs
• Scalability issues
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Retail priorities
EFFICIENT & SCALABLE Need to handle large volumes RESILIENT Downtime is expensive FLEXIBLE & MAINTAINABLE Business requirements change
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Need to go Reactive to be …
RESPONSIVE Customer experience, brand promise RESILIENT Handle failure at multiple levels ELASTIC Handle traffic spikes (without breaking the bank) MESSAGE-DRIVEN Enable all of the above
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Walmart.ca Re-architecture
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Walmart.ca re-architecture
ATG
Oracle
Product content management
JSPs
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Walmart.ca re-architecture
ATG
Oracle
REST API
Endeca search & merchandizing
REST API
Product content management
JSPs
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Walmart.ca re-architecture
ATG
Oracle
Endeca search & merchandizing
REST API
Akka, Redis
Product content management
JSPs
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Walmart.ca re-architecture
ATG
Oracle
Endeca search & merchandizing
REST API
Play
Akka, Redis
Product content management
JSON
JSPs
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Walmart.ca re-architecture
ATG
Oracle
REST API
Endeca search & merchandizing
REST API
Play
Akka, Redis
Product content management
JSON JSON
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Walmart.ca re-architecture
No. 1 +20%
+98%
Canada’s first responsively designed e-commerce site for a big box retailer
Increase in conversion in the first 4 weeks after launch
Increase in mobile orders
-36%
Decrease in average page load time
Awarded BEST E-COMMERCE SITE in large retailers by Retail Council of Canada
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Walmart.ca re-architecture
No. 1 +20%
+98%
Canada’s first responsively designed e-commerce site for a big box retailer
Increase in conversion in the first 4 weeks after launch
Increase in mobile orders
-36%
Decrease in average page load time
NO SYSTEM OUTAGES!
Awarded BEST E-COMMERCE SITE in large retailers by Retail Council of Canada
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Move to Functional Programming
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Move to Functional Programming
● Majority of the team are developers with a Java background
● Play provides an easy entry path to Scala / Reactive / Functional:
§ Based on familiar MVC patterns
§ Can start with Java style, mutation, blocking
§ Incrementally transition to Scala style, immutable, non-blocking
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Move to Functional Programming
1. No nulls (use Option)
2. No vars, mutable state*
3. Use higher-order functions (map, flatMap, filter, for-yield, etc.)
4. Business logic should be side-effect free (testability!)
5. Create and use strong types
*unless well justified (e.g. much clearer), and as small a scope as possible
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Move to Functional Programming
● Code should be a clear and concise as possible
● Types should be express intent and fit tightly
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Move to Functional Programming: Strong Types
sealed trait Language case object English extends Language
case object French extends Language def formatPrice(price: Price, lang: Language) = lang match {
case English => … case French => …
}
implicit val binder = new PathBindable[Language] {
… }
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Technical Tips & Features
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Tips & Features: Caching Futures (on-heap)
● Several concurrent requests for same data
● Whoever requests first initiates the Future (Promise)
● No locking required (narrow window between first request and when
Future is cached)
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Tips & Features: Handling JSON
Play Application Makes Heavy Use of JSON
• Consumes JSON view advice from Endeca
• Proxy & augment JSON data for web service calls
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Tips & Features: Play JSON macro
Consuming JSON (e.g. Endeca cartridges) case class Product(id: Long, name: String, …)
object Product {
implicit val formats = Json.format[Product] }
Json.toJson(product)
productJson.asOpt[Product]
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Tips & Features: ‘Almost Default’ Reads/Writes
OPEN CHALLENGE
Sometime we want an ‘almost default’ Reads/Writes
• e.g. use a default
• Read/write a few fields in a particular way
• e.g. format two dates in different ways
• (Could Shapeless case class generics macro help?)
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Tips & Features: Proxying and Augmenting JSON
Proxying JSON (e.g. most web services)
• Might want to augment a JSON response
• Don’t need to care about knowing the entire structure
• Play JSON transformers
• play-json-zipper can be helpful (github: mandubian)
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Tips & Features: Dependency Injection
CONTROLLER DEPENDENCIES (SERVICES)
• Use structural types for DI at the controller level
• Create a services module for each request
• Want access to request header (logging)
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Tips & Features: Dependency Injection
THREADLOCAL
• Inject dependencies in Global.getControllerInstance
• Initialize services module in Global.onRouteRequest, add to
ThreadLocal
• Pick up this value in the getControllerInstance and provide it to our
controller
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Tips & Features: Monadic Rendering
Page Model
• Template
• Zones
• Cartridges
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Rendering View Advice: Templates & Zones
The business user selects a template:
• Determines the page layout
• Each template has ~12 zones
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Rendering View Advice: Cartridges
… adds cartridges to the zones:
• ~100 cartridges
ProductImage
ProductDescription
ProductPurchase
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Rendering View Advice: Whole Page
• Endeca fills in data (product info)
• Play renders the cartridge as HTML
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Rendering View Advice: JSON to Visual Page • Tmpl1
• Header • Car1 • Car2
• LeftNav • Car3
• MainContent • Car4 • Car5 • Car6
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Rendering View Advice: JSON to HTML • Tmpl1
• Header • Car1 • Car2
• LeftNav • Car3
• MainContent • Car4 • Car5 • Car6
<body>! <div class=“header”>!! !…!
</div>! <div class=“leftNav”>!! !…!
</div>! !<div class=“main”>!! !…!
</div>!</body>!
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Rendering View Advice: Auxiliary Information
• Tmpl1 • Header
• Car1 • Car2
• LeftNav • Car3
• MainContent • Car4 • Car5 • Car6
<head>!
!
</head>!
<body>!
<div class=“header”>!
! !…!
</div>!
<div class=“leftNav”>!
! !…!
</div>!
!<div class=“main”>!
! !…!
</div>!
!
!
</body>!
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Rendering View Advice: Auxiliary Information
• Tmpl1 • Header
• Car1 • Car2
• LeftNav • Car3
• MainContent • Car4 • Car5 • Car6
<head>!
!
</head>!
<body>!
<div class=“header”>!
! !…!
</div>!
<div class=“leftNav”>!
! !…!
</div>!
!<div class=“main”>!
! !…!
</div>!
!
!
</body>!
CSS / JavaScript / RJS modules
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Rendering View Advice: Auxiliary Information
• Tmpl1 • Header
• Car1 • Car2
• LeftNav • Car3
• MainContent • Car4 • Car5 • Car6
<head>!
!
</head>!
<body>!
<div class=“header”>!
! !…!
</div>!
<div class=“leftNav”>!
! !…!
</div>!
!<div class=“main”>!
! !…!
</div>!
!
!
</body>!
CSS / JavaScript / RJS modules
JavaScript / RJS modules
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Rendering View Advice: Auxiliary Information
• Tmpl1 • Header
• Car1 • Car2
• LeftNav • Car3
• MainContent • Car4 • Car5 • Car6
<head>!
!
</head>!
<body>!
<div class=“header”>!
! !…!
</div>!
<div class=“leftNav”>!
! !…!
</div>!
!<div class=“main”>!
! !…!
</div>!
!
!
</body>!
CSS / JavaScript / RJS modules
JavaScript / RJS modules Cache control
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Monadic Rendering: ValidatedBuilder Monad
ValidatedBuilder[X] • “Parse/process” X • ≅ Future[(X, Boolean, Resources)]
• Error flag: • Determine if page should be cached
• Front-end resources • CSS • RequireJS modules • JavaScript snippets (+ page location requirements)
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Monadic Rendering: ValidatedBuilder Monad
ValidatedBuilder[X] • map and flatMap handle combining and propagating validity and
front-end resources • Code focuses on the essential task (JSON -> HTML) without clutter • Error prone ‘plumbing’ is handled by the monad abstraction
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Monadic Rendering: ValidatedBuilder Zone
val headerContent: VB[Seq[Cartridge]] = (viewAdvice \ “header”)
.as[Seq[JsValue]] // Seq[JsValue] .map(Cartridge.parse) // Seq[VB[Cartridge]]
.vbSeq // VB[Seq[Cartridge]]
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Monadic Rendering: ValidatedBuilder Template
val template: VB[Template] = for { header <- headerContent : VB[Seq[Cartridge]]
leftNav <- leftNavContent …
templateResult <- CayenneTemplate(header, leftNav, …)
} yield templateResult
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Monadic Rendering: ValidatedBuilder Page
for { content <- template.contents : Future[Template]
resources <- template.resources : Future[Resources] isCacheable <- template.isValid : Future[Boolean]
yield {
val result = template.render(resources) if (isCacheable)
result else
result.withHeaders(noCache: _*)
}
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Tips & Features: Dynamic Configuration
• Ops can make on the fly configuration changes
• Enable/disable services and site features
• Change endpoints
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Tips & Features: Dynamic Configuration
• Sends configuration delta to Play (JSON object)
• Play verifies the change (initialize services module)
• Each request sees a snapshot of the configuration
• Uses standard Play HOCON API
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Experience and Impressions
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Experience and Impressions ● Never need to say “no” to a client due to technical limitations,
● Heavily concurrency / parallelism, with very little headaches,
● Aggressive refactorings are surprisingly easy (thank you strong types).
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Outlook
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Outlook
NEW BREED OF PRODUCTS Reactive core
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Outlook
NEW BREED OF PRODUCTS Reactive core Middleware
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Outlook
NEW BREED OF PRODUCTS Reactive core Middleware Omnichannel CE
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Outlook
NEW BREED OF PRODUCTS Reactive core Middleware Omnichannel CE Streaming big data Machine intelligence
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Outlook
NEW BREED OF PRODUCTS Reactive core Middleware Omnichannel CE Streaming big data Machine intelligence CMS
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Outlook
NEW BREED OF PRODUCTS Reactive core Middleware Omnichannel CE Streaming big data Machine intelligence CMS BAAS REsponsiveSS
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Outlook
NEW BREED OF PRODUCTS Reactive core Middleware Omnichannel CE Streaming big data Machine intelligence CMS BAAS REsponsiveSS In store tech, IoT…
REACTIVE RETAIL BIG RETAIL GOES REACTIVE AT WALMART
Q & A
Ankur Mathur @anchormath Dana Harrington @danagharrington https://github.com/dana-harrington