DupalCon Barcelona 2015 - The journey from the request to the response

34ade09dd3d11004ca8ee4174fd3d6a2?s=47 Sarah KHALIL
September 30, 2015

DupalCon Barcelona 2015 - The journey from the request to the response

Let’s get in an adventure! Basically, what happens when a request is done until the response is rendered? When I first asked this question to a teammate, it was a pretext to see how I can learn most of concepts applied in the Symfony2 framework. This talk is about discovering (or re-discovering) how Symfony2 performs things internally to render a response: by going through a winding road, we’ll see how you can teach to your colleagues all of this.

34ade09dd3d11004ca8ee4174fd3d6a2?s=128

Sarah KHALIL

September 30, 2015
Tweet

Transcript

  1. The journey from the request to the Response Sarah Khalil

    - @saro0h
  2. WHO AM I? • Head of • Trainer & Developer

    • Enjoying sharer • Contributor to
  3. None
  4. http://bit.do/sfcon2015

  5. WHAT’S THE PLAN? • The philosophy of Symfony • Heart

    of Drupal : Dependency Injection Component • And Templating?
  6. PHILOSOPHY

  7. request GET /users HTTP/1.1 Host: 127.0.0.1:8000 User-Agent: curl/7.37.1

  8. request GET /users HTTP/1.1 Host: 127.0.0.1:8000 User-Agent: curl/7.37.1

  9. request GET /users HTTP/1.1 Host: 127.0.0.1:8000 User-Agent: curl/7.37.1 response HTTP/1.1

    200 OK Host: 127.0.0.1:8000 Content-Type: text/html; <html>Some content</html>
  10. request GET /users HTTP/1.1 Host: 127.0.0.1:8000 User-Agent: curl/7.37.1 response HTTP/1.1

    200 OK Host: 127.0.0.1:8000 Content-Type: text/html; <html>Some content</html> Symfony is an HTTP framework.
  11. HTTP request View Model Controller Routing component HTTP response front

    controller HttpKernel event listener HttpFoundation request HttpFoundation response
  12. HTTP request View Model Controller Routing component HTTP response front

    controller HttpKernel event listener HttpFoundation request HttpFoundation response
  13. None
  14. HTTP request

  15. HTTP request

  16. HTTP request front controller

  17. HTTP request front controller HttpFoundation request

  18. HTTP request front controller HttpKernel HttpFoundation request

  19. • HttpFoundation • Abstraction of the Request & the Response

    • HttpKernel • Turns the Request in a response COMPONENTS INVOLVED
  20. IN DRUPAL?

  21. $request  =  Request::createFromGlobals();   $response  =  $kernel-­‐>handle($request);   $response-­‐>send();  

    $kernel-­‐>terminate($request,  $response); front controller
  22. HTTP request front controller HttpKernel HttpFoundation request

  23. HTTP request front controller HttpKernel HttpFoundation request

  24. HTTP request front controller HttpKernel Routing component HttpFoundation request

  25. • Maps a URL to a set of parameters ROUTING

    COMPONENT homepage:      path:          /      defaults:  {  _controller:  Todo\Controller\TodoController::indexAction  }
  26. IN DRUPAL?

  27. HTTP request front controller HttpKernel Routing component HttpFoundation request

  28. HTTP request front controller HttpKernel Routing component HttpFoundation request

  29. HTTP request front controller HttpKernel Routing component Controller HttpFoundation request

  30. HTTP request front controller HttpKernel Routing component Controller HttpFoundation request

    View Model
  31. • A callable responsible of communication with the Model and

    the View layers. • It must return an HttpFoundation response. CONTROLLER
  32. CONTROLLER namespace  Todo\Controller;   use  Symfony\Component\HttpFoundation\Request;   use  Symfony\Component\HttpFoundation\Response; class

     TodoController   {        public  function  hello(Request  $request)        {                return  new  Response('Some  content');        }   }
  33. HTTP request View Model Controller Routing component front controller HttpKernel

    HttpFoundation request
  34. HTTP request View Model Controller Routing component front controller HttpKernel

    HttpFoundation request HttpFoundation response
  35. HTTP request View Model Controller Routing component front controller HttpKernel

    HttpFoundation request HttpFoundation response
  36. HTTP request View Model Controller Routing component HTTP response front

    controller HttpKernel HttpFoundation request HttpFoundation response
  37. None
  38. None
  39. HTTP request View Model Controller Routing component HTTP response front

    controller HttpKernel HttpFoundation request HttpFoundation response
  40. HTTP request View Model Controller Routing component HTTP response front

    controller HttpKernel HttpFoundation request HttpFoundation response event system
  41. EVENT DISPATCHER COMPONENT Allows to easily decouple code and plugin

    new features to an object without using inheritance.
  42. TWO MAIN CONCEPTS • Dispatch an Event • Listen /

    Subscribe to an event
  43. 1. EVENT The dispatched event is an object which carries

    all the needed data to retrieve into each listener.
  44. 2. LISTENER The listener can be any valid PHP «

    callable » like a function name, an instance method, a static method or a closure.
  45. EVENT LISTENER ≠ EVENT SUBSCRIBER

  46. EVENT SUBSCRIBER 1/2 namespace  SensioLabs\Article\Listener;   use  Symfony\Component\EventDispatcher\EventSubscriberInterface;   class

     ArticleListener  implements  EventSubscriberInterface   {   //  ...          public  static  function  getSubscribedEvents()          {                  return  [                          'article.save'    =>  [                                  [  'onInsertArticle',  10  ],                                  [  'onUpdateArticle',  5  ],                          ],                          'article.delete'  =>  [  'onDeleteArticle',  0  ],                  ];          }   }
  47. use  Symfony\Component\EventDispatcher\Event;   use  Symfony\Component\EventDispatcher\EventDispatcher;   $dispatcher  =  new  EventDispatcher();

      $dispatcher-­‐>addSubscriber(new  ArticleListener());   EVENT SUBSCRIBER 2/2
  48. EVENT LISTENER 1/2 namespace  SensioLabs\Article\EventListener;   use  Symfony\Component\HttpFoundation\Response;   use

     Symfony\Component\HttpKernel\Event\GetResponseEvent;   class  MyListener   {          public  function  onKernelRequest(GetResponseEvent  $event)          {                  if  (!$event-­‐>isMasterRequest())  {                          return;                  }                  $request  =  $event-­‐>getRequest();                  if  ($file  =  $request-­‐>attributes-­‐>get('_file'))  {                          $event-­‐>setResponse(new  Response('Some  content'));                  }          }   }
  49. EVENT LISTENER 2/2 use  Symfony\Component\EventDispatcher\Event;   use  Symfony\Component\EventDispatcher\EventDispatcher;   $dispatcher

     =  new  EventDispatcher();   $dispatcher-­‐>addListener(          KernelEvents::REQUEST,          [  new  MyListener(),  'onKernelRequest'  ]   );  
  50. EVENT DISPATCHER COMPONENT use  Symfony\Component\EventDispatcher\Event;   use  Symfony\Component\EventDispatcher\EventDispatcher;   $dp

     =  new  EventDispatcher();   //  Add  event  listeners  and/or  event  subscribers   $dp-­‐>dispatch('event.name',  new  Event());
  51. IN DRUPAL? services:      weather.job_listener:        

     class:  Drupal\weather\Listener\AddJobHeaderListener          arguments:  ['me@email.com']          tags:              -­‐  {  name:  event_subscriber  } services:      weather.job_listener:          class:  Drupal\weather\Listener\AddJobHeaderListener          arguments:  ['me@email.com']          tags:              -­‐  {  name:  kernel.event_listener,  event:   kernel.request,  method:  onKernelRequest  }
  52. 1.kernel.request 2.kernel.controller 3.kernel.view EVENTS TRIGGERED BY THE HTTPKERNEL COMPONENT 4.kernel.response

    5.kernel.terminate 6.kernel.finish_request
  53. ALL TOGETHER NOW !

  54. None
  55. HTTP request

  56. HTTP request

  57. HTTP request

  58. HTTP request front controller

  59. HTTP request front controller

  60. HTTP request front controller HttpKernel

  61. HTTP request front controller HttpKernel

  62. HTTP request Routing component front controller HttpKernel

  63. HTTP request Routing component front controller HttpKernel

  64. HTTP request Controller Routing component front controller HttpKernel

  65. HTTP request View Model Controller Routing component front controller HttpKernel

  66. HTTP request View Model Controller Routing component front controller HttpKernel

    HttpFoundation request
  67. HTTP request View Model Controller Routing component front controller HttpKernel

    HttpFoundation request HttpFoundation response
  68. HTTP request View Model Controller Routing component front controller HttpKernel

    HttpFoundation request HttpFoundation response
  69. HTTP request View Model Controller Routing component HTTP response front

    controller HttpKernel HttpFoundation request HttpFoundation response
  70. HTTP request View Model Controller Routing component HTTP response front

    controller HttpKernel event listener HttpFoundation request HttpFoundation response
  71. DRUPAL 8 AND SYMFONY

  72. DRUPAL 8 AND SYMFONY

  73. COMPONENTS USED symfony/class-loader symfony/css-selector symfony/dependency-injection symfony/event-dispatcher symfony/http-foundation symfony/http-kernel symfony/routing symfony/serializer

    symfony/validator symfony/yaml
  74. COMPONENTS USED symfony/class-loader symfony/css-selector symfony/dependency-injection symfony/event-dispatcher symfony/http-foundation symfony/http-kernel symfony/routing symfony/serializer

    symfony/validator symfony/yaml
  75. DEPENDENCY INJECTION The DI component allows you to standardize and

    centralize the way objects are constructed in your application.
  76. 3 KEY CONCEPTS 1. Service container 2. Services 3. Parameters

  77. 1. SERVICE CONTAINER Manages the instantiation of your service. Makes

    sure that there is only one instance of a service. Stores the parameters.
  78. 2. SERVICES PHP object. Perform global task. Does not have

    any state.
  79. 3. PARAMETERS Global configuration.

  80. IN DRUPAL?

  81. parameters:      weather_endpoint:  'http://api.openweathermap.org'      admin_email:  'admin@admin.com'  

    services:      weather.forecasts:          class:  Drupal\weather\Services\ForecastService          arguments:  ['@http_client',  '%weather_endpoint%']            weather.job_listener:              class:  Drupal\weather\Listener\AddJobHeaderListener              arguments:  ['%admin_email%']              tags:                  -­‐  {  name:  event_subscriber  }
  82. TEMPLATING

  83. TEMPLATING

  84. #  views/layout.twig   <!DOCTYPE  html>   <html>      

       <head>                  <meta  http-­‐equiv="Content-­‐Type"  content="text/html;   charset=UTF-­‐8">                  <title>{%  block  title  'Todo  Application'  %}</title>                  <link  rel="stylesheet"  media="screen"  type="text/css"  href="/   style.css"/>                  {%  block  stylesheets  ''  %}          </head>          <body>                  <div  id="container">                          <h1>                                  <a  href="index.php">My  Todos  List</a>                          </h1>                          <div  id="content">                                  {%  block  content  %}{%  endblock  %}                          </div>                          <div  id="footer">                                  (c)  copyright  -­‐  not  sensio                          </div>                  </div>                  {%  block  javascripts  ''  %}          </body>   </html>
  85. block title block stylesheets block content <html> </html> <head> </head>

    <body> </body> <!-- some html code --> block javascripts <!-- some html code -->
  86. #  views/home.twig   {%  extends  'layout.twig'  %}   {%  block

     title  'Tasks  Management'  %}   {%  block  content  %}          <form  action="/index.php/todo/new"  method="post">              <div>                  <label  for="title">Title:</label>                  <input  type="text"  id="title"  name="title"  size="45"/>                  <input  type="hidden"  name="action"  value="create"/>                  <button  type="submit">send</button>              </div>          </form>          <p>              There  are  <strong>{{  count  }}</strong>  tasks.          </p>   {%  endblock  %}
  87. IN DRUPAL? 1/3

  88. IN DRUPAL? 2/3 //  weather.module   /**    *  Implements

     hook_theme().    */   function  weather_theme()  {      $theme['forecasts']  =  [          'variables'  =>  ['country'  =>  NULL,  'city'  =>  NULL,  'forecast'  =>  NULL],           'template'  =>  'forecasts',      ];      return  $theme;   }
  89. IN DRUPAL?3/3 //  In  the  Controller   public  function  forecasts($country,

     $city)   {      $forecast  =  $this-­‐>forecastService-­‐>getForecasts($country,  $city);      return  [           '#theme'  =>  'forecasts',          '#country'  =>  $country,          '#city'  =>  $city,          '#forecast'  =>  $forecast,      ];    }
  90. http://twig.sensiolabs.org

  91. Need training? Come see us at the SensioLabs booth!

  92. Come see us at the SensioLabs booth! Wanna know more

    about
  93. Come see us at the SensioLabs booth! Wanna make jokes

    or know more about Lannister? @catlannister
  94. None
  95. Thank you! @saro0h speakerdeck.com/saro0h/ saro0h This is a zero guys!