You are here

protected function ResourceResponseSubscriber::renderResponseBody in Drupal 8

Same name in this branch
  1. 8 core/modules/jsonapi/src/EventSubscriber/ResourceResponseSubscriber.php \Drupal\jsonapi\EventSubscriber\ResourceResponseSubscriber::renderResponseBody()
  2. 8 core/modules/rest/src/EventSubscriber/ResourceResponseSubscriber.php \Drupal\rest\EventSubscriber\ResourceResponseSubscriber::renderResponseBody()
Same name and namespace in other branches
  1. 9 core/modules/rest/src/EventSubscriber/ResourceResponseSubscriber.php \Drupal\rest\EventSubscriber\ResourceResponseSubscriber::renderResponseBody()

Renders a resource response body.

During serialization, encoders and normalizers are able to explicitly bubble cacheability metadata via the 'cacheability' key-value pair in the received context. This bubbled cacheability metadata will be applied to the the response.

In versions of Drupal prior to 8.5, implicit bubbling of cacheability metadata was allowed because there was no explicit cacheability metadata bubbling API. To maintain backwards compatibility, we continue to support this, but support for this will be dropped in Drupal 9.0.0. This is especially useful when interacting with APIs that implicitly invoke rendering (for example: generating URLs): this allows those to "leak", and we collect their bubbled cacheability metadata automatically in a render context.

@todo Add test coverage for language negotiation contexts in https://www.drupal.org/node/2135829.

Parameters

\Symfony\Component\HttpFoundation\Request $request: The request object.

\Drupal\rest\ResourceResponseInterface $response: The response from the REST resource.

\Symfony\Component\Serializer\SerializerInterface $serializer: The serializer to use.

string|null $format: The response format, or NULL in case the response does not need a format, for example for the response to a DELETE request.

1 call to ResourceResponseSubscriber::renderResponseBody()
ResourceResponseSubscriber::onResponse in core/modules/rest/src/EventSubscriber/ResourceResponseSubscriber.php
Serializes ResourceResponse responses' data, and removes that data.

File

core/modules/rest/src/EventSubscriber/ResourceResponseSubscriber.php, line 160

Class

ResourceResponseSubscriber
Response subscriber that serializes and removes ResourceResponses' data.

Namespace

Drupal\rest\EventSubscriber

Code

protected function renderResponseBody(Request $request, ResourceResponseInterface $response, SerializerInterface $serializer, $format) {
  $data = $response
    ->getResponseData();

  // If there is data to send, serialize and set it as the response body.
  if ($data !== NULL) {
    $serialization_context = [
      'request' => $request,
      CacheableNormalizerInterface::SERIALIZATION_CONTEXT_CACHEABILITY => new CacheableMetadata(),
    ];

    // @deprecated In Drupal 8.5.0, will be removed before Drupal 9.0.0. Use
    // explicit cacheability metadata bubbling instead. (The wrapping call to
    // executeInRenderContext() will be removed before Drupal 9.0.0.)
    $context = new RenderContext();
    $output = $this->renderer
      ->executeInRenderContext($context, function () use ($serializer, $data, $format, $serialization_context) {
      return $serializer
        ->serialize($data, $format, $serialization_context);
    });
    if ($response instanceof CacheableResponseInterface) {
      if (!$context
        ->isEmpty()) {
        @trigger_error('Implicit cacheability metadata bubbling (onto the global render context) in normalizers is deprecated since Drupal 8.5.0 and will be removed in Drupal 9.0.0. Use the "cacheability" serialization context instead, for explicit cacheability metadata bubbling. See https://www.drupal.org/node/2918937', E_USER_DEPRECATED);
        $response
          ->addCacheableDependency($context
          ->pop());
      }
      $response
        ->addCacheableDependency($serialization_context[CacheableNormalizerInterface::SERIALIZATION_CONTEXT_CACHEABILITY]);
    }
    $response
      ->setContent($output);
    $response->headers
      ->set('Content-Type', $request
      ->getMimeType($format));
  }
}