class RequestHandler

Acts as intermediate request forwarder for resource plugins.

Hierarchy

Expanded class hierarchy of RequestHandler

File

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

Namespace

Drupal\rest
View source
class RequestHandler extends ContainerAware {

  /**
   * Handles a web API request.
   *
   * @param Symfony\Component\HttpFoundation\Request $request
   *   The HTTP request object.
   * @param mixed $id
   *   The resource ID.
   *
   * @return \Symfony\Component\HttpFoundation\Response
   *   The response object.
   */
  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;
  }

  /**
   * Generates a CSRF protecting session token.
   *
   * @return \Symfony\Component\HttpFoundation\Response
   *   The response object.
   */
  public function csrfToken() {
    return new Response(drupal_get_token('rest'), 200, array(
      'Content-Type' => 'text/plain',
    ));
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ContainerAware::$container protected property @api
ContainerAware::setContainer public function Sets the Container associated with this Controller. Overrides ContainerAwareInterface::setContainer
RequestHandler::csrfToken public function Generates a CSRF protecting session token.
RequestHandler::handle public function Handles a web API request.