From Drupal 8 Request to HTTP Response

dakala

Drupal is in the business of taking an HTTP Request and returning an HTTP Response. Generally speaking, that's the foundation of the web - you type in a URL into a browser and a request is sent to the server which replies with the appropriate response. The index.php file is the heart and soul of Drupal's compass to navigating the Request-Response journey. And it's usually both the entry and exit point to the application.

<?php

// index.php

use Drupal\Core\DrupalKernel;
use Symfony\Component\HttpFoundation\Request;

$autoloader = require_once 'autoload.php';

$kernel = new DrupalKernel('prod', $autoloader);

$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();

$kernel->terminate($request, $response);

The 7 stages outlined in this file are as follows:

  1. Use statements tell us to expect a hybrid engine of Drupal and Symfony
  2. Do some initial housekeeping with autoloader
  3. Create a Drupal-flavoured instance of HttpKernelInterface from Symfony
  4. Create a Request object from global variables
  5. The kernel handles the request and returns a Response object
  6. The response is sent - text, html, ajax, dialog, modal, json, rss etc.
  7. The kernel does some housekeeping afterwards.

Since this is the common behavioural pattern of web applications it makes sense for PHP applications and frameworks that share a similar philosophy or approach to programming to find a way to put their heads together and come up with a specification for dealing with this Request-Response journey.

The PHP Framework Interoperability Group (PHP-FIG) came up with a proposal, PSR-7: HTTP Messages Interface. The document crystallizes HTTP messages into 7 interfaces which a PHP library should implement if they subscribe to the specification, namely MessageInterface, RequestInterface, ResponseInterface, ServerRequestInterface, UriInterface, UploadedFileInterface and StreamInterface.

Drupal is an active participant in PHP-FIG. We can see the footprints of PSR-7 in Drupal 8 starting from the psr\http-message package in the vendor folder. As the package README says, the repository only holds all interfaces, classes and traits related to PSR-7 and this isn't an HTTP message implementation of its own. It is merely an interface that describes a HTTP message. It's up to different applications and frameworks, including Drupal, to implements these interfaces as they find suitable.

In different places we find -

  • use Psr\Http\Message\RequestInterface;
  • use Psr\Http\Message\ResponseInterface;
  • use Psr\Http\Message\UriInterface;
  • use Psr\Http\Message\ServerRequestInterface;

Psr\Http\Message\MessageInterface is the parent class of RequestInterface and ResponseInterface. Only Psr\Http\Message\UploadedFileInterface and Psr\Http\Message\StreamInterface aren't implemented in some form in Drupal 8.

Drupal 8, Symfony 2 and 3 and use Symfony HttpFoundation instead of PSR-7 directly. The Symfony community has taken a further step by implementing a bridge library between HttpFoundation and Zend Diactoros, a popular implementation of PSR-7.  This bridge is already included in Drupal core.

The current thinking is that the next major versions of Symfony and Drupal (4 and 9 respectively) could switch from HttpFoundation to PSR-7. However, another route to a full PSR-7 implementation might be via StackPHP which describes itself as "a convention for composing HttpKernelInterface middlewares."

Level of knowledge attendees should have before the session:
- HTTP requests and response
- How Drupal 8 leverages Symfony components

What the session will accomplish and what attendees will walk away having learned:
- Better understanding of how Drupal 8 works
- Drupal's limited implementation of PSR-7
- Challenges of a full implementation

Session Track

Coding and Development

Experience Level

Intermediate

Drupal Version