How to alter any response in Drupal 8 through Middleware

Middleware API gives us a lot of opportunities to intervene in the request or response in Drupal 8. I want to share a simple example how it can be useful.

You can get official information about Middleware API in Drupal 8 by this link. What is really important that the middleware will be performed on each request to your site.

It means that it should work fast. If some middleware works slow, it means that your site works slow. Be careful with the logic of your middleware.

Okay, let's start.

Step #1, define your middleware in the file "your_module.services.yml":

services:  
  your_module.middleware:
    class: Drupal\your_module\YourModuleAlterResponse
    tags:
      - { name: http_middleware, priority: 500 }

Step #2, create your plugin in "modules/custom/your_module/src/YourModuleAlterResponse.php":

<?php

namespace Drupal\your_module;

use Drupal\Component\Serialization\Json;
use Drupal\image\Entity\ImageStyle;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpFoundation\Request;

/**
 * Middleware to alter REST responses.
 */
class YourModuleAlterResponse implements HttpKernelInterface {
  /**
   * The wrapped kernel implementation.
   *
   * @var \Symfony\Component\HttpKernel\HttpKernelInterface
   */
  private $httpKernel;

  /**
   * @param  \Symfony\Component\HttpKernel\HttpKernelInterface $http_kernel
   *   Http Kernel.
   */
  public function __construct(HttpKernelInterface $http_kernel) {
    $this->httpKernel = $http_kernel;
  }

  /**
   * {@inheritdoc}
   */
  public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = TRUE) {
    $response = $this->httpKernel->handle($request, $type, $catch);
    // If it's request to upload file.
    if ($request->getRequestFormat() == 'hal_json' && $request->getPathInfo() == '/entity/file' && $request->getMethod() == 'POST') {
      // If we need preview.
      if (!empty($_GET['image_style'])) {
        $content = Json::decode($response->getContent());
        // If we have an url.
        if (!empty($content['uri'][0]['value'])) {
          if ($image_style = ImageStyle::load($_GET['image_style'])) {
            $content['preview'] = $image_style->buildUrl($content['uri'][0]['value']);
            $response->setContent(Json::encode($content));
          }
        }
      }
    }
    return $response;
  }
}

This middleware allows adding custom property into the response for a request of creating the file. It's not the best way to use the Middleware but it allows to understand the principle. Pretty good and simple example is BanMiddleware.php from Drupal Core. Also, you can check PageCache.php, it's more complicated Middleware, but very interesting. Also, it can help you learn more about caching in Drupal 8.

I hope that it was interesting for you!

Tags: