Home > Backend Development > PHP Tutorial > From Request to Response: A Journey into Drupal 8 Internals

From Request to Response: A Journey into Drupal 8 Internals

Jennifer Aniston
Release: 2025-02-17 11:11:38
Original
940 people have browsed it

Depth into Drupal 8 (and Symfony2): Request-to-response process

Core points

  • Drupal 8 uses Symfony2's HTTPKernel and HTTPFoundation components to process user requests and responses, encapsulate requests in an object-oriented manner, pass them to the application, and return responses.
  • The HTTPKernel component is the core of any Symfony-based application that starts the process in the index.php file and utilizes event-driven processes. This makes the application more flexible and tasks can be delegated to listeners for these events.
  • If the controller does not return a Response object, the kernel triggers the kernel.view event, and the subscriber is responsible for converting the controller's results into the actual Response object. This flexibility allows the controller to return any type of object as long as it is combined with the VIEW event subscriber that converts the object to the correct Response.
  • HTMLRenderer As the most commonly used main content renderer type, builds pages using the concept of page variants. This process occurs in the HTMLRenderer's prepare() method, which provides a #type => 'page' rendering array for the renderResponse() method, which wraps the main content. Then wrap it in the #type => 'html' rendering array and render it using the Renderer class.

In the first article on Drupal 8 module development, we learned a little about the routing aspects of this process. We have seen that creating pages with paths is now just a problem of declaring routes that match the controller. As we can see, the latter can return a rendered array that is interpreted as a marker and displayed in the main content area of ​​that page. But did you know that behind the scenes, Drupal actually converts that array to a Response object according to Symfony's HTTPKernelInterface regulations?

From Request to Response: A Journey into Drupal 8 Internals

In this article, I want to give us a deeper look at the internal structure of Drupal 8 (and Symfony2) and understand what actually happens (and what may happen) between the moment the user makes a request to the time they see the response they return thing). The examples I mentioned above are just one direction where this process can go, and today we will see other possibilities. The goal is to understand the flexibility of the system, which in turn can help us build great applications.

Before delving deeper, I highly recommend you check out this chart, which does a great job of synthesizing what is often called Rendering Pipeline. Although it seems to me that it represents more than the name suggests, because the rendering system is only part of the picture, albeit a large part.

Front-end controller (index.php)

Symfony2 is now an important part of Drupal. The latter uses many Symfony components, the most important components for this article are the HTTPKernel and HTTPFoundation components. Together, they are responsible for encapsulating user requests, passing them to the application, and then returning the returned content to the user in a consistent and object-oriented manner.

HTTPKernelInterface (you may have heard of it from other contexts as well) glues all of this together by receiving the Request object and always returning the Response object. A very simple but powerful concept.

This process starts inside the index.php file, which first generates the Request object and passes it to the HTTPKernel::handle() method. The latter is then responsible for returning the Response object. At a high level, this happens in both Drupal applications and Symfony applications (or any other application that utilizes HTTPKernel components).

HTTPKernel and Events

HTTPKernel is the core of any Symfony-based application. As we can see, its handle() method has a lot of responsibility in preparing the response, and it does this with an event-driven process. This makes the application very flexible, and the heavy work is always delegated to the listener of these events.

If you look at the previous chart, you can see that this workflow is described in the second column, which basically represents the adhesive in terms of Symfony and Drupal.

It starts with the first event called kernel.request. Subscribers of this event handle various tasks. But in Drupal 8, two very important tasks are format negotiation and routing. The first determines the type of response that needs to be returned (html, json, image, pdf, etc.), and the second determines the code responsible for processing this response (the _controller key defined by the route in the routing.yml file). However, like most steps in this event workflow, if the listener returns the response object, the process skips most subsequent steps (stop propagation) and goes directly to kernel.response.

The second event is kernel.controller, which is called after the application knows which controller is responsible for processing the request. At this point, the listener can still perform some overriding operations on it. Immediately following this step, the kernel is responsible for parsing the parameters passed to the controller. One such operation in Drupal is to load objects based on the ID found in the request (such as a node) and provide these objects directly to the controller. The controller will then eventually be called with the corresponding parameters.

The controller is responsible for returning a response of some kind. If it returns a Response object, the process jumps to the kernel.response event. The latter listener can perform last-minute modifications to the object, such as modifying the header or the content itself. And after getting it from the handle() method, the front-end controller sends it back to the user using the send() method on the Response object and terminates the process.

From Request to Response: A Journey into Drupal 8 Internals

A deeper understanding of rendered arrays

If the controller does not return a Response object, the kernel triggers the last event: kernel.view. Its subscribers are responsible for converting the controller's results into actual Response objects. So, this means you can return any type of object from the controller, as long as you combine it with the VIEW event subscriber that converts that object to the correct Response.

However, as we see in the example, the controller returns the rendered array most of the time. This usually represents the main content of the page (similar to the page callback in Drupal 7).

To handle this, Drupal 8 has a MainContentViewSubscriber responsible for converting this array into the correct Response object. It does this by using a specific MainContentRenderer selected in the format negotiation phase discussed earlier. Although some of these renderers are already available, the default renderer used is HtmlRenderer.

HTMLRenderer

Since this is the most commonly used main content renderer type, let's take a closer look at how it builds the page.

A cool thing in this process is the concept of page variation. This means that the HTMLRenderer dispatches an event that is responsible for finding out which type of page to use to wrap the main content rendering array: RenderEvents::SELECT_PAGE_DISPLAY_VARIANT. By default, SimplePageVariant is used unless the Block module is enabled. In this case, BlockPageVariant will start and allow blocks to be placed in the area around the main content. If you want, you can subscribe to this event in your own module and provide your own variation.

All this happens in the prepare() method of HTMLRenderer, which provides a #type => 'page' render array for renderResponse() method that wraps the main content array. The latter two are wrapped in the #type => 'html' rendering array, which is finally rendered using the Renderer class (the equivalent of drupal_render() in Drupal 7). The generated HTML string is added to the Response object and returned to the front-end controller.

While this is a very high-level overview of the process, this is basically what happened. Now we have a Response object, which means the kernel can dispatch its kernel.response event. After that, the front-end controller can send the Response directly back to the user and terminate the process.

Conclusion

In this article, we explored internally Drupal 8 (and Symfony2) by tracking responses from user requests to server returns. We have seen how Drupal 8 takes advantage of HTTPKernel and HTTPFoundation Symfony2 components, and how it basically sits on top of those components. Additionally, we see how the adhesive between them is composed of events dispatched by kernels, which Drupal subscribes to for all its features. Finally, we have seen how to build and return HTML pages to the user with the help of the rendering pipeline.

I believe that understanding what's going on behind the scenes in the Drupal 8 application will allow you to create a great application by knowing exactly where to get to this process. I believe that if you only take one thing away from this article, it should be the word flexibility. Because the flexibility to build what we need in Drupal 8 is far more than anything in Drupal 7. It has indeed become modern.

FAQs about Drupal 8's internal structure (FAQ)

What is the main difference between Drupal 7 and Drupal 8?

Drupal 8 introduces several major changes compared to Drupal 7. It has a new theme engine called Twig, which is safer and more flexible. Drupal 8 is also more mobile-friendly and includes more built-in fields. It better supports multilingual sites with improved language management and translation support. Additionally, Drupal 8 integrates better with third-party platforms due to the widespread use of Symfony components.

Drupal 8 How to handle requests and responses?

Drupal 8 Use the Symfony HttpKernel component to handle requests and responses. When a request is made, Drupal 8 creates a Request object and passes it to the HttpKernel. HttpKernel then uses the routing system to determine which controller should process the request. The controller processes the request and returns a Response object, which HttpKernel sends back to the client.

What is the role of the routing system in Drupal 8?

The routing system in Drupal 8 is responsible for mapping the URL to a specific controller. It uses the routing definition provided by the module to determine which controller should handle the given request. The routing system also supports dynamic routing, which can be changed according to the state of the system.

How does Drupal 8's theme system work?

Drupal 8's theme system uses Twig, a flexible and secure template engine. The topic in Drupal 8 consists of a .info.yml file (providing metadata about the topic) and a Twig template file (defining HTML output). The theme system also supports template inheritance, allowing themes to extend and overwrite templates from other themes or modules.

How do I develop custom modules in Drupal 8?

Developing a custom module in Drupal 8 includes creating a .info.yml file to provide metadata about the module, and a .module file to contain the module's PHP code. The module may also contain other files, such as routing files that define routes and service files that define services. Drupal 8 uses object-oriented programming and Symfony components to make writing reusable and testable code easier.

What are the benefits of using Drupal 8 for web development?

Drupal 8 provides many benefits for web development. It uses Symfony components to make it more powerful and flexible. It supports responsive design out of the box, making it easier to create a mobile-friendly website. Drupal 8 also improves multilingual support, better SEO capabilities and a more user-friendly management interface.

Drupal 8 How to handle database interactions?

Drupal 8 uses the database API to handle database interactions. The Database API provides an abstraction layer on top of SQL, allowing developers to write database queries without having to understand the details of the underlying database engine. It also supports dynamic query, transaction and schema management.

What is the role of event scheduler in Drupal 8?

The event scheduler in Drupal 8 is used to manage events and event listeners. When an event occurs, the event scheduler notifies all registered listeners, which can then take action. This allows modules to interact with each other in a decoupled way.

Drupal 8 How to handle cache?

Drupal 8 has a complex cache system that helps improve performance. It supports multiple cached backends, including database, file and memory-based backends. Drupal 8 also has a cache tagging system that allows fine-grained failure of cached data.

How do I extend Drupal 8's functionality?

The functionality of Drupal 8 can be extended through modules and themes. Modules add new features or modify existing features, while themes control the look and feel of the site. Drupal 8 also supports plug-ins that allow the exchange of features, as well as services, and provide reusable features that can be injected into other parts of the system.

This revised output maintains the original meaning while rephrasing sentences and paragraphs, avoiding direct copying. The image URLs are preserved. The formatting is adjusted for better reading.

The above is the detailed content of From Request to Response: A Journey into Drupal 8 Internals. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template