Handles a web API request.
Symfony\Component\HttpFoundation\Request $request: The HTTP request object.
mixed $id: The resource ID.
\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;
}