As a web application, Magento 2’s web request processing flow is similar to all other web framework flows, but offers more extension points to third-party developers. In this session, we will walk through a web request path in the Magento 2 application, from index.php to browser JS application, and will look at extension points available on that path.
5. Entry Point
• Index.php or pub/index.php – web application
• Static.php – retrieve dynamically generated static files
• Get.php – retrieve media from database
• Cron.php – run commands by Cron
• bin/magento – command line tool
8. Bootstrap::initObjectManager
• We hate init* methods. M1 was full of them
• Loads initial configuration (config.php, env.php, di.xml)
• Loads etc/di.xml files from all modules (global configuration)
• Last point where we have valid init* methods
12. Application Areas
• Configuration scopes
• etc/<areaCode>/* in module folder
• Loaded on top of global configuration
• Admin, Frontend, Webapi_Rest, Webapi_Soap, Cron
19. Front Controller
public function dispatch(RequestInterface $request){
// …
foreach ($this->routerList as $router) {
$actionInstance = $router->match($request);
if ($actionInstance) {
$result = $actionInstance->execute();
break;
}
}
// …
return $result;
}
/lib/internal/Magento/Framework/App/FrontController.php
20. Routing
• Every area has own set of routers
• Important routers: standard for frontend & admin for admin
• Both configured in /etc/<areaCode>/routes.xml
• Cover 95% of cases (?)
23. Front Controller
public function dispatch(RequestInterface $request){
// …
foreach ($this->routerList as $router) {
$actionInstance = $router->match($request);
if ($actionInstance) {
$result = $actionInstance->execute();
break;
}
}
// …
return $result;
}
/lib/internal/Magento/Framework/App/FrontController.php
24. Action Controllers
• Path handlers
• Single method execute
• By convention located in Controller folder of a module
• Different rules for GET and POST
• Request object should not be passed further. Extract arguments and
pass them separately.
25. Action Controllers
class View extends MagentoFrameworkAppActionAction
{
// constructor and properties
public function execute()
{
// do something
$result = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
$result->setPath('*/*/*');
// or
$result = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
return $result;
}
}
My/Module/Controller/Blog/Post/View.php
27. POST Action Controllers
• Do not render pages. Layout is forbidden
• Only place for application workflow management (redirect,
messages, session)
• All business logic should be delegated to Service Contracts
• Request object should not be passed further. Extract arguments and
pass them separately.
28. POST Action Controller
class Save extends MagentoFrameworkAppActionAction
{
public function execute()
{
$post = $this->postFactory->create();
$post->setTitle($this->request->getParam('title'));
$post->setText($this->request->getParam('text'));
$post = $this->postRepository->save($post);
$result = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
$result->setPath(’blogs/post/view’, [’post_id' => $post->getId()]);
}
}
My/Module/Controller/Blog/Post/Save.php
29. Service Contracts
• Represent public API of a module
• Covered by Backwards Compatibility Policy
• Located Api folder of a module and marked with @api
• Expose procedural API (Service Interfaces) that communicate with
Data Transfer Objects (Data Interfaces)
31. Persistence
• Use Resource Models to Load/Save/Delete data
• Use Collections to load lists of data
• load, save, and delete on model are deprecated
32. POST Action Controller
class Save extends MagentoFrameworkAppActionAction
{
public function execute()
{
$post = $this->postFactory->create();
$post->setTitle($this->request->getParam('title'));
$post->setText($this->request->getParam('text'));
$post = $this->postRepository->save($post);
$result = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
$result->setPath(’blogs/post/view’, [’post_id' => $post->getId()]);
return $result;
}
}
My/Module/Controller/Blog/Post/Save.php
34. GET Action Controller
class View extends MagentoFrameworkAppActionAction
{
// constructor and properties
public function execute()
{
$result = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
return $result;
}
}
/app/code/My/Module/Controller/Blog/Post/View.php
35. GET Action Controllers
• Do not reference blocks directly. They may not exist on the page
• Do not pre-load models and put them to registry. Load what you
need from blocks.
• DO NOTHING in Action Controllers that respond to GET requests
and render pages (only return PageResult)
40. Blocks
• Do not reference other sibling and parent blocks
• Do not perform state-modifications
• Retrieve data from public services
• Do not pass Request object further, extract arguments, and pass
them
43. GET Action Controller
class View extends MagentoFrameworkAppActionAction
{
// constructor and properties
public function execute()
{
$result = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
return $result;
}
}
/app/code/My/Module/Controller/Blog/Post/View.php
Changed to bin/mageno
Magento has multiple entrypoints
Depends on the client
Creates the instance of application
What is type check?
Initializes Object Manager
Init is not a good pattern, it encourages temporal coupling
What does it mean “Last point where we have valid init* methods?”
Creates application object using object manager
DI is already initialized; all the plugins and preferences will be picked up
Runs application
Load areas
Area defines scopes of configuration
Allows to configure frontend and backend differently
Area distinguishes different parts of application
Anything special about this screenshot?
- In order to separate the concerns, all custom logic applicable to all controllers should be added as plugins to the front controller
- This follows AOP approach
- Some logic might be applicable to POST only, like CSRF
Front controller invokes routing logic
Custom routes can be created
Most likely standard ones will only be needed
Admin routes takes into account “admin” part of the url
Configuration of the route which tells that blog part of url will invoke action controllers in My_Blog module
Request routing searches for action controller based on the request url
Once request is routed it means that action controller is found
Front controller invokes action controller
What is “Path handlers”?
Action Controller creates Response based on Request
We will talk more on types of responses later
This is ideal GET action controller
Layout defines which blocks are on the page requested by GET
Block are referenced by Layout object based on this declaration
Template is the place where most of the request processing logic happens on GET
Block should have just methods needed by the template to render
Block should not have generic methods to render itself. It should be injected with the helper classes instead
We are moving to direction where block is a generic class and all the functions are injected as dependencies
Block should not implement this logic by itself, it should delegate calls to more appropriate classes
Template renders information which block provides
Result is representation of HTTP response
Different Results can be created by Action controller
Action controller returns result
Application get result from the middleware and renders it