Spryker Hackathon Q1 2016
-
Upload
fabian-wesner -
Category
Software
-
view
836 -
download
2
Transcript of Spryker Hackathon Q1 2016
Hackathon 16/17.03.2016
2016 Spryker Systems GmbH / Hackathon Q1/16 2
Introduc?on
About me
2016 Spryker Systems GmbH / Hackathon Q1/16 3
Fabian Wesner >= 2015 Spryker Systems 2012 – 2014 Project A Ventures 2011 Rocket Internet 2010 Zalando
Contact me
2016 Spryker Systems GmbH / Hackathon Q1/16 4
Follow me on twiQer to get #Spryker updates and photos from this hackathon. hQps://twiQer.com/FabianWesner Ø This presenta?on is available on Slideshare!
Spryker Bird’s eye view
2016 Spryker Systems GmbH / Hackathon Q1/16 5
Code principles
2016 Spryker Systems GmbH / Hackathon Q1/16 6
Spryker (pragma?cally) follows the SOLID-‐Principles,
Principles of cohesion,
and Principles of Coupling.
Spryker welcomes Clean Code!
Highly recom
mended!
Code quality
2016 Spryker Systems GmbH / Hackathon Q1/16 7
h"ps://scru*nizer-‐ci.com/g/spryker/spryker/?branch=develop
2016 Spryker Systems GmbH / Hackathon Q1/16 8
Layered architecture
Four Layer Architecture
2016 Spryker Systems GmbH / Hackathon Q1/16 9
A bundle in a nutshell
2016 Spryker Systems GmbH / Hackathon Q1/16 10
Zed – Structure of a bundle
2016 Spryker Systems GmbH / Hackathon Q1/16 11
Zed – Presenta?on layer
2016 Spryker Systems GmbH / Hackathon Q1/16 12
Spryker uses Twig templa?ng engine.
Zed – Presenta?on layer – Technologies
2016 Spryker Systems GmbH / Hackathon Q1/16 13
Twig templa?ng engine
NPM for packaging
Webpack for collec?ng all the assets, load them,
check them, compile and op?mize them
Zed – Communica?on layer
2016 Spryker Systems GmbH / Hackathon Q1/16 14
Controller, Tables, Forms and Plugins.
Powered by Silex micro-‐framework and some Symfony components
Zed – Business layer
2016 Spryker Systems GmbH / Hackathon Q1/16 15
The facade is the API (entry point) to this layer.
Here you implement your business models!
Guideline:
-‐ Every model implements an interface
-‐ Dependency Injec?on only
Zed – Business layer -‐ Facade
2016 Spryker Systems GmbH / Hackathon Q1/16 16
The facade acts like an internal API.
The main responsibility of the facade is to hide the internal implementa?on.
class CustomerFacade extends AbstractFacade!{ !! public function updateCustomer() ! { ... } !! public function restorePassword() ! { ... } !! public function setDefaultShippingAddress() ! { ... } !!} !
Zed – Business layer -‐ Facade
2016 Spryker Systems GmbH / Hackathon Q1/16 17
The façade of the current bundle is available with
in Controllers and Plugins.
$this->getFacade() !
Spryker uses
Each bundle ships with a part of the schema.
QueryContainer acts as API
En??es and query objects are generated.
Zed – Persistence layer
2016 Spryker Systems GmbH / Hackathon Q1/16 18
Zed – Persistence layer – QueryContainer
2016 Spryker Systems GmbH / Hackathon Q1/16 19
The QueryContainer contains all queries of a bundle.
QueryContainer is used by the other layers with:!
$this->getQueryContainer() !
Zed – Persistence layer – Schema XML
2016 Spryker Systems GmbH / Hackathon Q1/16 20
<?xml version="1.0"?> !<database name="zed”> ! ! <table name="spy_customer" idMethod="native" phpName="SpyCustomer"> ! <column name="id_customer" required="true" type="INTEGER” /> ! <column name="email" required="true" size="255" type="VARCHAR" /> ! <column name="first_name" size="100" type="VARCHAR" /> ! <column name="last_name" size="100" type="VARCHAR" /> ! <unique> ! <unique-column name="email" /> ! </unique> ! </table> !!</database> !
Zed – Persistence layer –En??es&Queries
2016 Spryker Systems GmbH / Hackathon Q1/16 21
// Entity !$customerEntity = new SpyCustomer(); !$customerEntity->setFirstName('John') ! ->setFirstName('John') ! ->setLastName('Doe') ! ->save(); !!// Query object !$customerQuery = new SpyCustomerQuery(); !$customerEntity = $customerQuery!
->filterByFirstName('John') !->findOne(); !
!
2016 Spryker Systems GmbH / Hackathon Q1/16 22
Packaging with bundles -‐ The modular monolith -‐
Zed = Monolith?
2016 Spryker Systems GmbH / Hackathon Q1/16 23
Zed
Zed consists of bundles
2016 Spryker Systems GmbH / Hackathon Q1/16 24
A bundle is a “func?onal unit”.
Bundles are decoupled and provide an explicit API.
They follow the packaging principles!
Currently there are > 100 bundles.
Managed by
Zed = Modular Monolith
2016 Spryker Systems GmbH / Hackathon Q1/16 25
Each bundle consists of (up to) 4 layers
2016 Spryker Systems GmbH / Hackathon Q1/16 26
Connec?ng bundles
2016 Spryker Systems GmbH / Hackathon Q1/16 27
Connec?ng bundles
2016 Spryker Systems GmbH / Hackathon Q1/16 28
Dependency Provider
2016 Spryker Systems GmbH / Hackathon Q1/16 29
class CartDependencyProvider extends AbstractBundleDependencyProvider!{ !! public function provideBusinessLayerDependencies(Container $container) ! { ! $container[self::FACADE_CALCULATION] = function (Container $container)
{ ! return $container->getLocator()->calculation()->facade(); ! }; !! return $container; ! } !} !
2016 Spryker Systems GmbH / Hackathon Q1/16 30
Programming with Spryker
Yves client
2016 Spryker Systems GmbH / Hackathon Q1/16 31
Yves client – Usage
2016 Spryker Systems GmbH / Hackathon Q1/16 32
class CartOperationHandler extends BaseHandler!{ ! public function add($sku, $quantity, $optionValueUsageIds = []) ! { ! $itemTransfer = new ItemTransfer(); ! $itemTransfer->setSku($sku); ! $itemTransfer->setQuantity($quantity); !! $this->addProductOptions($optionValueUsageIds, $itemTransfer); !! $quoteTransfer = $this->cartClient->addItem($itemTransfer); ! $this->cartClient->storeQuote($quoteTransfer); ! } !} !
Transfer objects
2016 Spryker Systems GmbH / Hackathon Q1/16 33
$customerTransfer = new CustomerTransfer(); !$customerTransfer! ->setEmail('[email protected]') ! ->setFirstName('John') ! ->setLastName('Doe'); ! !echo $customerTransfer->getFirstName(); // echos 'John' !!
<transfer name="Customer"> ! <property name="email" type="string" /> ! <property name="firstName" type="string" /> ! <property name="lastName" type="string" /> !</transfer> !
Factories -‐ Usage
2016 Spryker Systems GmbH / Hackathon Q1/16 34
class CartFacade extends AbstractFacade!{ ! public function add(CartChangeTransfer $cartChangeTransfer) ! { ! return $this->getFactory()->createCartOperation() ! ->add($cartChangeTransfer); ! } ! ! public function remove(CartChangeTransfer $cartChangeTransfer) ! { ! return $this->getFactory()->createCartOperation() ! ->remove($cartChangeTransfer); ! } !
Factories -‐ Example
2016 Spryker Systems GmbH / Hackathon Q1/16 35
class CartBusinessFactory extends AbstractBusinessFactory!{ ! /** ! * @return \Spryker\Zed\Cart\Business\Model\OperationInterface! */ !
public function createCartOperation() ! { ! return new Operation( ! $this->createStorageProvider(), ! $this->getCalculatorFacade(), ! $this->getItemGrouperFacade() ! ); ! } !} !
Dependency Injec?on with Interfaces
2016 Spryker Systems GmbH / Hackathon Q1/16 36
class Operation implements OperationInterface!{ ! protected $cartStorageProvider; ! protected $calculationFacade; ! protected $itemGrouperFacade; !! public function __construct( ! StorageProviderInterface $cartStorageProvider, ! CartToCalculationInterface $calculationFacade, ! CartToItemGrouperInterface $itemGrouperFacade, ! ) { ! $this->cartStorageProvider = $cartStorageProvider; ! $this->calculationFacade = $calculationFacade; ! $this->itemGrouperFacade = $itemGrouperFacade; ! } !} !!!
Extension with Plugins
2016 Spryker Systems GmbH / Hackathon Q1/16 37
class CalculationDependencyProvider extends SprykerCalculationDependencyProvider!{ ! protected function getCalculatorStack (Container $container) ! { ! return [ ! #Item calculators ! new ItemGrossAmountsCalculatorPlugin(), ! new ProductOptionGrossSumCalculatorPlugin(), !! #GrandTotal! new GrandTotalTotalsCalculatorPlugin(), ! new GrandTotalWithDiscountsCalculatorPlugin(), !! #TaxTotal! new TaxTotalsCalculatorPlugin(), ! ]; ! } !
Plugin example
2016 Spryker Systems GmbH / Hackathon Q1/16 38
class GrandTotalTotalsCalculatorPlugin extends AbstractPlugin ! implements CalculatorPluginInterface!{ ! public function recalculate(QuoteTransfer $quoteTransfer) ! { ! $this->getFacade()->calculateGrandTotalTotals($quoteTransfer); ! } !} !
Plugins are the most important concept for extension in Spryker. They are everywhere!
Thurday
2016 Spryker Systems GmbH / Hackathon Q1/16 39
Important concepts
Order Management in Spryker
2016 Spryker Systems GmbH / Hackathon Q1/16 40
Cronjob scheduling
2016 Spryker Systems GmbH / Hackathon Q1/16
Cronjobs are executed via Jenkins.
// See jobs.php!// Send emails every 10 minutes !$jobs[] = [ ! 'name' => 'send-mails', ! 'command' => '$PHP_BIN vendor/bin/console mail:send-mail', ! 'schedule' => '*/10 * * * *', ! 'enable' => true, ! 'run_on_non_production' => true, ! 'stores' => ['DE', 'FR'], !]; !
vendor/bin/console setup:jenkins:generate!
41
h"p://zed.de.spryker.dev:10007/
Mul? store
2016 Spryker Systems GmbH / Hackathon Q1/16 42
A store is a business unit Osen a country shop
The code is shared and localizable You can extend classes and templates for each store.
One team ó n Stores
Dedicated database per store
A store can have mul?ple locales Mul?-‐language
Release management (Preview)
2016 Spryker Systems GmbH / Hackathon Q1/16 43
No global version for Spryker! Spryker V2
Each bundle has a version number > 100 bundles
Seman?c versioning
Con?nuous delivery of atomic releases Monday: Cart 2.0.0
Tuesday: Cms 3.1.0 Thursday: Cart 2.1.0
Scaling (implementa?on example)
2016 Spryker Systems GmbH / Hackathon Q1/16 44
Yves load-‐balancer
Zed load-‐balancer
Yves phpApp
Yves phpApp
Yves phpApp
Zed Main phpApp*
Zed phpApp
DB
Redis
Elas?c search
scale
read / write read / write write
read
read
*Zed main server only: run cronjobs and post
deployment hooks
scale
Master-‐master or master-‐slave configura@on
Spryker hos?ng
2016 Spryker Systems GmbH / Hackathon Q1/16 45
Spryker follows The Twelve-‐Factor App methodology Runs on any cloud environment and bare-‐metal Solu?on partners for hos?ng available Talk to us Out-‐of-‐the-‐box integra?on with Heroku (coming soon) Seamless con?nuous delivery with Github and Heroku Pipelines
Spryker documenta?on
2016 Spryker Systems GmbH / Hackathon Q1/16 46
hQp://spryker.github.io
2016 Spryker Systems GmbH / Hackathon Q1/16 47
A proven technology built in real-‐world projects for ambi?ous and non-‐standard business models.
Spryker Systems GmbH Julie-‐Wolshorn-‐Strasse 1
10115 Berlin Germany
[email protected] Phone: +49 40 328 929 631
Fax: +49 40 328 929 699
www.spryker.com www.kassenzone.de
www.digitalkaufmann.de www.goto.project-‐a.com
48 2016 Spryker Systems GmbH / Hackathon Q1/16