The life of a request

← The life of a request

Ashterix

docs(articles): Magento and Symfony examples side by side, request lifecycle as a Mermaid diagram

en/articles/magento-to-symfony/basics/lifecycle.md +15 −12

The life of a request

In Magento a request goes through the FrontController, the router list and the action's execute(). In Symfony HttpKernel follows the same path, but every step is an event anyone can subscribe to: routing, security, argument conversion, exception handling. Understand this diagram, and most of Symfony's "magic" becomes ordinary event listeners.

public/index.php
  → Kernel::handle(Request)
  → kernel.request       RouterListener finds the route, then Firewall: who the user is
  → kernel.controller
  → ArgumentResolver     Request, entities, DTOs
  → Controller
      returned a Response      → kernel.response
      returned a non-Response  → kernel.view → kernel.response
      threw an exception       → kernel.exception → kernel.response
  → Response::send()
  → kernel.terminate
flowchart TD
  A["public/index.php"] --> B["Kernel::handle(Request)"]
  B --> C{{"kernel.request"}}
  C -->|"RouterListener finds the route"| C2["Firewall: who the user is"]
  C2 --> D{{"kernel.controller"}}
  D --> E["ArgumentResolver: Request, entities, DTOs"]
  E --> F["Controller"]
  F -->|"returned a Response"| H{{"kernel.response"}}
  F -->|"returned something else"| G{{"kernel.view"}}
  G --> H
  H --> I["Response::send()"]
  I --> J{{"kernel.terminate"}}
  F -. "exception" .-> X{{"kernel.exception"}}
  X --> H
Symfony step Closest in Magento What happens there
public/index.php, Kernel pub/index.php, Bootstrap, App\Http::launch() Loading the compiled container.
kernel.request: RouterListener (priority 32) FrontController::dispatch(), RouterList::match() The route is written into the Request attributes.
kernel.request: Firewall (priority 8) area + session, admin authentication plugin Authentication, the user token.
kernel.controller controller_action_predispatch, plugins on dispatch() This is where #[IsGranted], #[Cache] fire.
ArgumentResolver none; getParam() by hand An entity by id, a DTO from JSON, the current user.
Controller ActionInterface::execute() Your code.
kernel.view none Turning a non-Response into a Response, e.g. #[Template].
kernel.response controller_front_send_response_before Headers, cookies, the Web Profiler toolbar.
kernel.terminate none Work after the response is sent: logs, emails.
kernel.exception ExceptionHandler, noroute 404/403/500, error pages.

To see all listeners and their priorities: bin/console debug:event-dispatcher kernel.request.