Successfully reported this slideshow.
Your SlideShare is downloading. ×

Magento Live Australia 2016: Request Flow

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Loading in …3
×

Check these out next

1 of 45 Ad

Magento Live Australia 2016: Request Flow

Download to read offline

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.

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.

Advertisement
Advertisement

More Related Content

Slideshows for you (20)

Similar to Magento Live Australia 2016: Request Flow (20)

Advertisement

Recently uploaded (20)

Advertisement

Magento Live Australia 2016: Request Flow

  1. 1. Magento 2 Request Flow
  2. 2. Magento 2 Architect Eugene Tulika
  3. 3. Entry Point Everything starts here
  4. 4. 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
  5. 5. Entry Point require __DIR__ . '/app/bootstrap.php'; $bootstrap = MagentoFrameworkAppBootstrap::create(BP, $_SERVER); $app = $bootstrap->createApplication(MagentoFrameworkAppHttp::class); $bootstrap->run($app); /index.php
  6. 6. Bootstrap::createApplication public function createApplication($type, $arguments = []) { $this->initObjectManager(); $application = $this->objectManager->create($type, $arguments); // … type check return $application; } /lib/internal/Magento/Framework/App/Bootstrap.php
  7. 7. 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
  8. 8. Bootstrap::createApplication public function createApplication($type, $arguments = []) { $this->initObjectManager(); $application = $this->objectManager->create($type, $arguments); // … type check return $application; } /lib/internal/Magento/Framework/App/Bootstrap.php
  9. 9. Entry Point require __DIR__ . '/app/bootstrap.php'; $bootstrap = MagentoFrameworkAppBootstrap::create(BP, $_SERVER); $app = $bootstrap->createApplication(MagentoFrameworkAppHttp::class); $bootstrap->run($app); /index.php
  10. 10. ApplicationHttp public function launch() { $frontName = $this->_request->getFrontName(); $areaCode = $this->areaList->getCodeByFrontName($frontName); $this->state->setAreaCode($areaCode); $this->objectManager->configure($this->_configLoader->load($areaCode)); $frontController = $this->objectManager->get(FrontControllerInterface::class); $result = $frontController->dispatch($this->_request); $result->renderResult($this->_response); return $this->_response; } /lib/internal/Magento/Framework/App/Http.php
  11. 11. Application Areas • Configuration scopes • etc/<areaCode>/* in module folder • Loaded on top of global configuration • Admin, Frontend, Webapi_Rest, Webapi_Soap, Cron
  12. 12. Middleware Going down the rabbit hole of the onion rings
  13. 13. Middleware function (request) : response • Function applied to request in order to generate response • PSR-7
  14. 14. ApplicationHttp public function launch() { $frontName = $this->_request->getFrontName(); $areaCode = $this->areaList->getCodeByFrontName($frontName); $this->state->setAreaCode($areaCode); $this->objectManager->configure($this->_configLoader->load($areaCode)); $frontController = $this->objectManager->get(FrontControllerInterface::class); $result = $frontController->dispatch($this->_request); $result->renderResult($this->_response); return $this->_response; } /lib/internal/Magento/Framework/App/Http.php
  15. 15. Middleware Dispatch Authentication CSRF Checks Page Cache HTTP Request HTTP Response
  16. 16. Middleware • Add your plugin on front controller if you want some logic executed on all controllers • Keep POST & GET in mind
  17. 17. Routing
  18. 18. 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
  19. 19. 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 (?)
  20. 20. Routing <config> <router id="standard"> <route id=”blog" frontName=”blog"> <module name=”My_Blog" /> </route> </router> </config> /My/Module/etc/frontend/routes.xml
  21. 21. Actions
  22. 22. 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
  23. 23. 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.
  24. 24. 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
  25. 25. POST
  26. 26. 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.
  27. 27. 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
  28. 28. 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)
  29. 29. Service Contracts My/Module/Api/PostRepository.php class PostRepository implements MyModuleApiPostRepositoryInterface { // .. public function save(PostInterface $post) { $this->postResourceModel->save($post); return $post; } }
  30. 30. Persistence • Use Resource Models to Load/Save/Delete data • Use Collections to load lists of data • load, save, and delete on model are deprecated
  31. 31. 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
  32. 32. GET
  33. 33. 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
  34. 34. 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)
  35. 35. Layout /My/Module/view/frontend/layout/blog_post_view.xml <page> <body> <referenceBlock name="container"> <block class="MyModuleBlockBlogPostView” name=”blog.post.view” template=”My_Module::blog/post/view.phtml"/> </referenceBlock> </body> </page>
  36. 36. Blocks /My/Module/view/frontend/templates/blog/post/view.phtml <?php $post = $block->getBlogPost(); ?> <article> <header> <h1><?php echo $block->escapeHtml($post->getTitle());?></h1> <span class="date"> <?php echo $block->formatDate($post->getPublicationDate());?> </span> <a href="<?php echo $block->getBlogLink($post); ?>" class="blog"> <?php echo $block->escapeHtml(__('To Blog'));?> </a> </header> <?php echo $post->getText(); ?> </article>
  37. 37. Blocks namespace MyModuleBlockBlogPost; class View { public function getBlogPost() { return $this->postRepository->get($this->request->getParam('post_id')); } public function getBlogLink(Post $post) { $this->urlBuilder->getUrl('blogs', ['blog_id' => $post->getBlogId()]); } } /My/Module/Block/Blog/Post/View.php
  38. 38. Blocks /My/Module/view/frontend/templates/blog/post/view.phtml <?php $post = $block->getBlogPost(); ?> <article> <header> <h1><?php echo $block->escapeHtml($post->getTitle());?></h1> <span class="date"> <?php echo $block->formatDate($post->getPublicationDate());?> </span> <a href="<?php echo $block->getBlogLink($post); ?>" class="blog"> <?php echo $block->escapeHtml(__('To Blog'));?> </a> </header> <?php echo $post->getText(); ?> </article>
  39. 39. 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
  40. 40. Response
  41. 41. Action Results namespace MagentoFrameworkController; class ResultFactory { const TYPE_JSON = 'json'; const TYPE_RAW = 'raw'; const TYPE_REDIRECT = 'redirect'; const TYPE_FORWARD = 'forward'; const TYPE_LAYOUT = 'layout'; const TYPE_PAGE = 'page'; public function create($type, array $arguments = []) { // ... return $resultInstance; } } /lib/internal/Magento/Framework/Controller/ResultFactory.php
  42. 42. 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
  43. 43. ApplicationHttp public function launch() { $frontName = $this->_request->getFrontName(); $areaCode = $this->areaList->getCodeByFrontName($frontName); $this->state->setAreaCode($areaCode); $this->objectManager->configure($this->_configLoader->load($areaCode)); $frontController = $this->objectManager->get(FrontControllerInterface::class); $result = $frontController->dispatch($this->_request); $result->renderResult($this->_response); return $this->_response; } /lib/internal/Magento/Framework/App/Http.php
  44. 44. Q & A

Editor's Notes

  • Request flow process governs the application
  • 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

×