From Drupal 8 Request to HTTP Response
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:
- Use statements tell us to expect a hybrid engine of Drupal and Symfony
- Do some initial housekeeping with autoloader
- Create a Drupal-flavoured instance of HttpKernelInterface from Symfony
- Create a Request object from global variables
- The kernel handles the request and returns a Response object
- The response is sent - text, html, ajax, dialog, modal, json, rss etc.
- 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