public function RequestHandler::handle

Handles a web API request.

Parameters

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

mixed $id: The resource ID.

Return value

\Symfony\Component\HttpFoundation\Response The response object.

File

drupal/core/modules/rest/lib/Drupal/rest/RequestHandler.php, line 34
Definition of Drupal\rest\RequestHandler.

Class

RequestHandler
Acts as intermediate request forwarder for resource plugins.

Namespace

Drupal\rest

Code

public function handle(Request $request, $id = NULL) {
  $plugin = $request->attributes
    ->get(RouteObjectInterface::ROUTE_OBJECT)
    ->getDefault('_plugin');
  $method = strtolower($request
    ->getMethod());
  $resource = $this->container
    ->get('plugin.manager.rest')
    ->getInstance(array(
    'id' => $plugin,
  ));

  // Deserialze incoming data if available.
  $serializer = $this->container
    ->get('serializer');
  $received = $request
    ->getContent();
  $unserialized = NULL;
  if (!empty($received)) {
    $format = $request
      ->getContentType();

    // Only allow serialization formats that are explicitly configured. If no
    // formats are configured allow all and hope that the serializer knows the
    // format. If the serializer cannot handle it an exception will be thrown
    // that bubbles up to the client.
    $config = $this->container
      ->get('config.factory')
      ->get('rest.settings')
      ->get('resources');
    $enabled_formats = $config[$plugin][$request
      ->getMethod()];
    if (empty($enabled_formats) || isset($enabled_formats[$format])) {
      $definition = $resource
        ->getPluginDefinition();
      $class = $definition['serialization_class'];
      try {
        $unserialized = $serializer
          ->deserialize($received, $class, $format);
      } catch (UnexpectedValueException $e) {
        $error['error'] = $e
          ->getMessage();
        $content = $serializer
          ->serialize($error, $format);
        return new Response($content, 400, array(
          'Content-Type' => $request
            ->getMimeType($format),
        ));
      }
    }
    else {
      throw new UnsupportedMediaTypeHttpException();
    }
  }

  // Invoke the operation on the resource plugin.
  // All REST routes are restricted to exactly one format, so instead of
  // parsing it out of the Accept headers again, we can simply retrieve the
  // format requirement. If there is no format associated, just pick HAL.
  $format = $request->attributes
    ->get(RouteObjectInterface::ROUTE_OBJECT)
    ->getRequirement('_format') ?: 'hal_json';
  try {
    $response = $resource
      ->{$method}($id, $unserialized, $request);
  } catch (HttpException $e) {
    $error['error'] = $e
      ->getMessage();
    $content = $serializer
      ->serialize($error, $format);

    // Add the default content type, but only if the headers from the
    // exception have not specified it already.
    $headers = $e
      ->getHeaders() + array(
      'Content-Type' => $request
        ->getMimeType($format),
    );
    return new Response($content, $e
      ->getStatusCode(), $headers);
  }

  // Serialize the outgoing data for the response, if available.
  $data = $response
    ->getResponseData();
  if ($data != NULL) {
    $output = $serializer
      ->serialize($data, $format);
    $response
      ->setContent($output);
    $response->headers
      ->set('Content-Type', $request
      ->getMimeType($format));
  }
  return $response;
}