Much of the conversation in the Drupal 8 development cycle has focused on “NIH vs. PIE.” In Drupal 8 we have replaced a fear of anything “Not-Invented-Here” with an embrace of tools that were “Proudly-Invented-Elsewhere.” In practice, this switch means removing “drupalisms,” sections of code created for Drupal that are understood only by (some) Drupal developers. In their place, we have added external libraries or conventions used by a much wider group of people. Drupal has become much clearer, much more explicit about its intentions by making this kind of change all over the codebase.
Replacing drupal_http_request with Guzzle
For instance we have gotten rid of our own “drupal_http_request()” and replaced it with the invented-elsewhere Guzzle library. Guzzle is a stand-alone tool written in PHP for making HTTP requests. Here is the change record that describes how code written in Drupal 7 would be modified to use the new library in Drupal 8. Ultimately it was Guzzle’s superior feature set that made it replace drupal_http_request. Guzzle can do a lot more than drupal_http_request and it does so in a much clearer fashion.
From the change record we see an example of Guzzle:
$client = \Drupal::httpClient();
$request = $client->createRequest('GET', $feed->url);
$request->addHeader('If-Modified-Since', gmdate(DATE_RFC1123, $last_fetched));
Compared to an example from Drupal 7:
$headers = array('If-Modified-Since' => gmdate(DATE_RFC1123, $last_fetched));
$result = drupal_http_request($feed->url, array('headers' => $headers));
The intentions of the code from Guzzle are much more explicit. The method “addHeader” is being called. Any developer could read that line and see what is happening. In the case of the Drupal 7 code the reader would be guessing. And sure, it might be easy enough to guess what drupal_http_request will do when it is passed multidimensional arrays. But it takes a lot of mental overhead for developers to think through the implication of each key within a multidimensional array.
It is not a coincidence that Guzzle, a library shared among many PHP projects, requires developers to be very clear about their intentions. Replacing drupal_http_request with Guzzle made Drupal’s code more explicit and comprehensible. There are numerous other examples where adopting or pursuing a concept from outside Drupal made Drupal itself clearer.
Perhaps the clearest example of this shift is the switch to classed objects. Prior to Drupal 8, much of Drupal Core still showed its roots in PHP4 when support for object-oriented concepts was immature. Now instead of Drupal entities being represented simply as a “stdClass”, each entity type has its own class with defined properties and methods. Writing actual classes, methods, and interfaces encourages the Drupal community to think harder about what each entity is meant to do.
Drupal has a history of taking our “node” concept and bending it mercilessly to replace less developed parts of core. Anyone else remember usernode, which made a node for every user? When users and nodes were both shoehorned onto the same type of generic class it was easier to justify using one to make up for the shortcomings of the other and muddle our definitions by doing so. Actual classes force us to think more clearly.
Along with the usage of classed-objects has come the adoption of interfaces. One of the problems interfaces have helped solved is the pain of registering new functionality like field widgets. In Drupal 7 and prior, adding a new field formatter meant writing a set of hooks—some of which were absolutely required and others varied by use case. Writing hook_field_formatter_info implies writing hook_field_formatter_prepare_view, but it doesn’t require it. In Drupal 8 the we have Drupal\Core\Field\FormatterInterface to tell us exactly what is needed by a formatter and module writers can extend Drupal\Core\Field\FormatterBase to avoid rewriting boilerplate.
Interfaces also enable Drupal 8 to put services in a Dependency Injection Container. Again, Drupal is replacing NIH with PIE. Previous versions of Drupal assumed that any portion of code could access the global state at any time for any reason. This assumption implies that isolating a section of code so that it can be replaced is very difficult or impossible. In Drupal 8 many corners of Drupal, like breadcrumb handling, have be rewritten into a “service” which is carried in a “container”. The service should declare exactly what it depends and exactly what it will do (through an interface). This enables developers to replace one service with another version. Here is a detailed breakdown from Larry Garfield on how to do so with breadcrumbs. Again, for Drupal to use an outside concept, it’s own code must be more explicit.
Chasing an invented-elsewhere caching strategy has made Drupal’s internal caching system much clearer. Inspired by Facebook’s Big Pipe caching strategy, Drupal developers led by Fabian Franz and Wim Leers have made huge improvements to Drupal 8 caching. And of course they have made the caching system more explicit in doing so. The idea of Big Pipe is simple: make a page load fast by sending only a skeleton of markup and then filling in all of the separately-cached blocks of content. For that strategy to work, each block must be very explicit about how long it can be cached and which changes to context or content would invalidate it. Now, when rendering something, a developer is expected to explicitly state:
The cache tags. These are data points like node ids. The idea is that if a node is resaved, every cache that declared the node’s id as a cache tag can be invalidated.
The cache contexts. Some render elements vary based on more global concepts like the language of the current request/user or the role of the current user. This addition makes it much easier to do something like showing a full article to subscribers and a truncated article to anonymous users.
The max-age of the cache. Some elements have to be regenerated every 10 minutes. Some can stay cached as long as their tags and contexts remain unchanged. Before Drupal 8, cache ages were much more of a guesswork operation.
For more information, watch this talk from Drupalcon Barcelona from Wim Leers and Fabian Franz.
Drupal 8’s configuration management strategy is perhaps the most touted new feature and it brings plenty of PIE. The Configuration Management Initiative helped pave the way for standardized, exportable configuration; a concept developers from other systems expect as a matter of course. The discussions within the Configuration Management Initiative considered a number of different export formats like JSON and XML. YAML was ultimately chosen and that format is now used throughout Drupal for different purposes like the definition of services, libraries, CSS breakpoints and more. Even the drupalism of .info files in modules and themes has be replaced with this widely understood, invented-elsewhere format.
Additionally, core has taken concepts from CTools module for how configuration moves from the file system to the database to a cache. Now in Drupal 8, configuration can be exported to the file system (in .yml files) to be committed to git and moved across environments. The .yml files can then be imported into a database in a consistent fashion where they are stored and cached.
The main improvement over Drupal 7 is the consistency across Drupal subsystems. In Drupal 7, a developer had to remember that “overridden” meant one thing when Features module used that word in relation to Field configuration and “overridden” meant a slightly different thing when Views UI used it in relation to an exported View. By treating configuration in a consistent manner across subsystems the whole architecture becomes more cohesive.
Increased explicitness often was not the main goal of the above changes. The developers leading those changes often just wanted a better system that was easier to work with. In doing so, we’ve made a version of Drupal that should be clearer and more understandable to developers new to Drupal. We do not have to explain the difference between Filter module storage and Panels. We can just say “our configurations are all stored in the same way”. Drupal becomes more approachable and will travel further because of it.Topics: Drupal Planet, Drupal