protected function ResourceResponseValidator::validateResponse in JSON:API 8
Same name and namespace in other branches
- 8.2 src/EventSubscriber/ResourceResponseValidator.php \Drupal\jsonapi\EventSubscriber\ResourceResponseValidator::validateResponse()
Validates a response against the JSON API specification.
Parameters
\Symfony\Component\HttpFoundation\Response $response: The response to validate.
\Symfony\Component\HttpFoundation\Request $request: The request containing info about what to validate.
Return value
bool FALSE if the response failed validation, otherwise TRUE.
1 call to ResourceResponseValidator::validateResponse()
- ResourceResponseValidator::doValidateResponse in src/
EventSubscriber/ ResourceResponseValidator.php - Wraps validation in an assert to prevent execution in production.
File
- src/
EventSubscriber/ ResourceResponseValidator.php, line 162
Class
- ResourceResponseValidator
- Response subscriber that validates a JSON API response.
Namespace
Drupal\jsonapi\EventSubscriberCode
protected function validateResponse(Response $response, Request $request) {
// If the validator isn't set, then the validation library is not installed.
if (!$this->validator) {
return TRUE;
}
// Do not use Json::decode here since it coerces the response into an
// associative array, which creates validation errors.
$response_data = json_decode($response
->getContent());
if (empty($response_data)) {
return TRUE;
}
$schema_ref = sprintf('file://%s/schema.json', implode('/', [
$this->appRoot,
$this->moduleHandler
->getModule('jsonapi')
->getPath(),
]));
$generic_jsonapi_schema = (object) [
'$ref' => $schema_ref,
];
$is_valid = $this
->validateSchema($generic_jsonapi_schema, $response_data);
if (!$is_valid) {
return FALSE;
}
// This will be set if the schemata module is present.
if (!$this->schemaFactory) {
// Fall back the valid generic result since schemata is absent.
return TRUE;
}
// Get the schema for the current resource. For that we will need to
// introspect the request to find the entity type and bundle matched by the
// router.
$resource_type = $request
->get(Routes::RESOURCE_TYPE_KEY);
$route_name = $request->attributes
->get(RouteObjectInterface::ROUTE_NAME);
// We shouldn't validate related/relationships.
$is_related = strpos($route_name, '.related') !== FALSE;
$is_relationship = strpos($route_name, '.relationship') !== FALSE;
if ($is_related || $is_relationship) {
// Fall back the valid generic result since schemata is absent.
return TRUE;
}
$entity_type_id = $resource_type
->getEntityTypeId();
$bundle = $resource_type
->getBundle();
$output_format = 'schema_json';
$described_format = 'api_json';
$schema_object = $this->schemaFactory
->create($entity_type_id, $bundle);
$format = $output_format . ':' . $described_format;
$output = $this->serializer
->serialize($schema_object, $format);
$specific_schema = Json::decode($output);
if (!$specific_schema) {
return $is_valid;
}
// We need to individually validate each collection resource object.
$is_collection = strpos($route_name, '.collection') !== FALSE;
// Iterate over each resource object and check the schema.
return array_reduce($is_collection ? $response_data->data : [
$response_data->data,
], function ($valid, $resource_object) use ($specific_schema) {
// Validating the schema first ensures that every object is processed.
return $this
->validateSchema($specific_schema, $resource_object) && $valid;
}, TRUE);
}