Headless Magento - Meet Magento Poland 2017
- 2. #MM17PL
• Magento developer
• Lead @ FitForMe
• Co-organiser MMNL,
Unconf, MageStackDay,
Meetups
• Avid community member
twitter.com/sandermangel
linkedin.com/in/sandermangel
github.com/sandermangel
- 4. #MM17PL
What is headless architecture
"Headless architecture means an application offering APIs that abstract away business logic
for a multitude of clients to consistently and repeatedly execute the same tasks."
- 12. #MM17PL
So we take a different
approach
• Magento will be a client &
provide data
• Implement a basic data
warehouse
• Which is fed by, and queried
by various services separated
by domains
• Isolate data & business logic
per domain
That allows for a smooth integration
- 15. #MM17PL
Leverage middleware for a
stable environment
storage
source consumer server
● Normalize & combine data
● Offer stable APIs for clients
● Insulate from future changes
- 18. #MM17PL
Build on standardised libraries
● There is a solution for everything
already out there
● Use popular libraries, preferably
adhering to a PSR protocol
● Don't overcomplicate dependency
injection
● Think carefully about what you need
and spend time finding the best
option
[...]
"require": {
"php": ">=7.0",
"slim/slim": "^3.1",
"monolog/monolog": "^1.17",
"cache/filesystem-adapter": "^0.4.0",
"guzzlehttp/guzzle": "^6.2",
"cache/array-adapter": "^0.5.0",
"illuminate/database": "^5.4",
"yadakhov/insert-on-duplicate-key": "^1.1",
"symfony/console": "^3.3",
"league/oauth1-client": "^1.7"
}
[...]
- 19. #MM17PL
Build on standardised libraries
● slimphp - Routing, DI
● monolog - gives insight in what the service does
for monitoring and debugging
● cache/… - stores certain API calls, temporary data
● guzzle - offers a way to consume APIs over http
● illuminate/database - Laravel ORM (personal
preference)
● Insert-on-duplicate.... - not a default option in
illuminate/database but a must for me
● symfony/console - for cronjobs and commandline
tasks
● league/oauth1-client - offers built in Magento 1
REST integration
[...]
"require": {
"php": ">=7.0",
"slim/slim": "^3.1",
"monolog/monolog": "^1.17",
"cache/filesystem-adapter": "^0.4.0",
"guzzlehttp/guzzle": "^6.2",
"cache/array-adapter": "^0.5.0",
"illuminate/database": "^5.4",
"yadakhov/insert-on-duplicate-key": "^1.1",
"symfony/console": "^3.3",
"league/oauth1-client": "^1.7"
}
[...]
- 20. #MM17PL
Build on standardised libraries
● SlimPHP project as basis
● One module in src some basic
setup files needed by SlimPHP
● Keep it simple and self-contained
- 21. #MM17PL
Some learnings
● Single purpose
● It should feel overly simple
● Within the service, separate tasks
● Document, document, document
● Write integration tests for the API
endpoints
● Log everything
- 23. #MM17PL
Exposing data
● Read only
● Easy to integrate
● Offer sorting, filtering, and a host of
other query options
● Be very fast (d'oh)
● Standardized & easily scalable
- 25. #MM17PL
Enabling various integrations
protected function _prepareCollection()
{
[...]
try {
$client = new Client();
$res = $client->request('GET', $helper->getBaseUrl(0) . 'quarantine?'.
http_build_query([ 'limit' => $limit, 'page' => $page, 'sort' => $columnId, 'sortdir'
=> $dir, 'filters' => (array)$filter, '', '&'));
} catch (Exception $error) {
Mage::logException($error);
$this->setCollection($collection); // set a dummy empty collection
return $this;
}
$data = json_decode($res->getBody(), true);
$lastPage = $data['to'];
array_walk($data['data'], function($order) use (&$collection) {
$collection->addItem(
new Varien_Object(
[ 'shipping_date' => $order['shipping_date'],
'order_reference' => $order['order_reference'],
'customer_reference' => $order['customer_reference'],
'updated_at' => $order['updated_at'],
'shipping_fullname' => "{$order['shipping_firstname']}
{$order['shipping_middlename']} {$order['shipping_lastname']}",
]
)
);
});
$collection->setCurPage($page);
$collection->setLastPageNumber($lastPage);
$collection->setSize($lastPage * $limit);
$this->setCollection($collection);
● Magento 1 grids
● Ajax calls for smaller values
● Data imports
● Communication between services
● ...
- 27. #MM17PL
Caching
● How dynamic is dynamic content
● Cache is all about control
● Think of a strategy upfront
https://github.com/magespecialist/m2-M
SP_APIEnhancer
Magento 2 API enhancer
- 31. #MM17PL
Monolithic
● Dedicated / VPS server
○ Offered by all hosting
companies
○ Easy to maintain
○ Does not scale easily
○ If one goes down...
Distributed
● Instances on a cloud
○ Scales easily
○ Environments are isolated
○ Requires more knowledge
○ Can be harder to
administrate
- 32. #MM17PL
API gateway
● Allow for easy service discovery
● Handle authentication, call rate limiting
● Routing
- http://microservices.io/patterns/apigateway.html
- https://www.nginx.com/blog/building-microservic
es-using-an-api-gateway/
- 33. #MM17PL
API gateway
● Allow for easy service discovery
● Handle authentication, call rate limiting
● Routing
- http://microservices.io/patterns/apigateway.html
- https://www.nginx.com/blog/building-microservic
es-using-an-api-gateway/
- 34. #MM17PL
Output format
There are great solution for better
documenting, discovery and output
formatting.
However, standardising output across
a large set of APIs has it's pitfalls as
no implementation is ever perfect
- 35. #MM17PL
Summary
● By offloading tasks from Magento we keep
it fast and lightweight
● Storing data in a central place and making
it available via REST apis makes for easy
integration
● Headless can start by adding some of
those APIs to the existing back- or frontend
● Using lightweight php frameworks with
limited features makes for easy to develop
and fast applications