In a Drupal site, when a user interacts with the system (for example, by accessing a URL, submitting a form, or consuming an API), Drupal processes the request through an entry and exit cycle — this is what we call Inbound and Outbound processing.
These two mechanisms allow Drupal to:
Let us look at all of this in detail with concrete examples.
Inbound Processing applies to everything the user sends to the system:
GET, POST),Imagine we want to redirect paths /products to /product while keeping Drupal's internal logic intact.
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class InboundPathSubscriber implements EventSubscriberInterface {
public static function getSubscribedEvents() {
return ['kernel.request' => ['onKernelRequest', 30]];
}
public function onKernelRequest(RequestEvent $event) {
$request = $event->getRequest();
$path = $request->getPathInfo();
if ($path === '/products') {
$request->server->set('REQUEST_URI', '/product');
}
}
}Here, we use the kernel.request event to intercept the URL before Drupal resolves the router.
Outbound Processing occurs when Drupal generates a response (HTML, JSON, etc.). It is often used to:
Url::fromRoute()),Suppose you want to transform all /user/ID links into /profile/ID during HTML rendering:
use Drupal\Core\PathProcessor\OutboundPathProcessorInterface;
use Symfony\Component\HttpFoundation\Request;
use Drupal\Core\Render\BubbleableMetadata;
class OutboundPathProcessor implements OutboundPathProcessorInterface {
public function processOutbound($path, &$options = [], Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) {
if (strpos($path, '/user/') === 0) {
return str_replace('/user/', '/profile/', $path);
}
return $path;
}
}Declaration in services.yml:
services:
my_module.path_processor.outbound:
class: Drupal\my_module\OutboundPathProcessor
tags:
- { name: path_processor_outbound, priority: 100 }| Situation | Inbound | Outbound |
|---|---|---|
| Modify the path before it is resolved | Yes | No |
| Modify a link before displaying it | No | Yes |
| Rewrite URL parameters | Yes | Yes |
| Add HTTP headers | No | Yes |
| Handle conditional redirection | Yes | No |
/fr/products to route to /en/product./fr/products, /en/product...).PathProcessorManager orchestrates these operations in Drupal Core.
\Drupal::logger() to trace processed paths.The Inbound and Outbound systems in Drupal are powerful tools for controlling the flow of HTTP data. Whether you are building a multilingual site, a headless site, or simply want to customize your site's paths, these hooks give you fine-grained control over data entry and exit — without modifying Drupal core.