2

I have JSON API with filters. Its working fine. For example:

{baseURL}/jsonapi/node/article?filter[X]=Y&sort=title&fields[node--article]=title,drupal_internal__nid

At the end of the Response I want to add some extra values. After digging through the jsonapi module, I found a Class file where the Response data is being prepared and sent from.

core/modules/jsonapi/src/Normalizer/JsonApiDocumentTopLevelNormalizer.php

In the normalize function, I want to add my info something like this:

$document['MY_INFO'] = "This is the extra Information";

The code for normalize function is:

public function normalize($object, $format = NULL, array $context = []) {
  assert($object instanceof JsonApiDocumentTopLevel);
  $data = $object->getData();
  $document['jsonapi'] = CacheableNormalization::permanent([
    'version' => JsonApiSpec::SUPPORTED_SPECIFICATION_VERSION,
    'meta' => [
      'links' => [
        'self' => [
          'href' => JsonApiSpec::SUPPORTED_SPECIFICATION_PERMALINK,
        ],
      ],
    ],
  ]);
  if ($data instanceof ErrorCollection) {
    $document['errors'] = $this->normalizeErrorDocument($object, $format, $context);
  }
  else {
    // Add data.
    // @todo: remove this if-else and just call $this->serializer->normalize($data...) in https://www.drupal.org/project/jsonapi/issues/3036285.
    if ($data instanceof EntityReferenceFieldItemListInterface) {
      $document['data'] = $this->normalizeEntityReferenceFieldItemList($object, $format, $context);
    }
    else {
      $document['data'] = $this->serializer->normalize($data, $format, $context);
    }
    // Add includes.
    $document['included'] = $this->serializer->normalize($object->getIncludes(), $format, $context)->omitIfEmpty();
    // Add omissions and metadata.
    $normalized_omissions = $this->normalizeOmissionsLinks($object->getOmissions(), $format, $context);
    $meta = !$normalized_omissions instanceof CacheableOmission
      ? array_merge($object->getMeta(), ['omitted' => $normalized_omissions->getNormalization()])
      : $object->getMeta();
    $document['meta'] = (new CacheableNormalization($normalized_omissions, $meta))->omitIfEmpty();
  }
  // Add document links.
  $document['links'] = $this->serializer->normalize($object->getLinks(), $format, $context)->omitIfEmpty();
  // Every JSON:API document contains absolute URLs.
  return CacheableNormalization::aggregate($document)->withCacheableDependency((new CacheableMetadata())->addCacheContexts(['url.site']));
}

What will be the right way to achieve this ? Of course we don't want to modify the same class file. Which class/file should be created to alter this and what will be the right way to add a value like this ?

$document['MY_INFO'] = "This is the extra Information";

Update: I found a way to add my extra values to it using:

$document['MY_INFO'] = CacheableNormalization::permanent(["XX"=> 'MY INFORMATION']);

Now my question is how do I implement it in my custom module? I don't want to edit the core files.

1
  • You probably don't want to do this at the json:api level, it would be better to do it at the node entity level so that your extra information is available regardless of how the node is viewed.
    – Lambic
    Nov 19, 2021 at 15:18

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.