I’m trying to extend Serialization to get the JSON Field module to return a JSON object instead of stringified JSON.
Goal: When I access an entity that contains a JSON field using JSON:API, I want a JSON object for the field value (currently, the stringified JSON is returned).
I think what I need to do is to extend one of the core normalizers and use it to add a json_decode()
step.
There is some documentation on how Serializer handles entities but it is out-of-date (last updated in 2017 before JSON:API was part of core, and the current code looks nothing like what is shown.)
I tried extending FieldNormalizer in /json_field/src/Normalizer/JsonFieldNormalizer.php
.
However, I’m not confident that this is the correct approach, as there is also a FieldItemNormalizer and TypedDataNormalizer. To change how a field is output in JSON:API, which class should I extend?
<?php namespace Drupaljson_fieldNormalizer; use DrupalCoreFieldFieldDefinitionInterface; use Drupaljson_fieldPluginFieldFieldTypeNativeJSONItem; use DrupaljsonapiJsonApiResourceResourceObject; use DrupaljsonapiNormalizerFieldNormalizer; use DrupaljsonapiNormalizerValueCacheableNormalization; use DrupaljsonapiResourceTypeResourceType; class JsonFieldNormalizer extends FieldNormalizer { /** * {@inheritdoc} */ protected $supportedInterfaceOrClass = NativeJSONItem::class; /** * {@inheritdoc} */ public function normalize($field, $format = NULL, array $context = []) { $field_name = $field->getName(); Drupal::logger('json_field')->info("Field has name $field_name"); assert($field instanceof NativeJSONItem); /** @var DrupalCoreFieldFieldItemListInterface $field */ $normalized_items = $this->normalizeFieldItems($field, $format, $context); assert($context['resource_object'] instanceof ResourceObject); return $context['resource_object']->getResourceType()->getFieldByInternalName($field->getName())->hasOne() ? array_shift($normalized_items) ?: CacheableNormalization::permanent(NULL) : CacheableNormalization::aggregate($normalized_items); }
And I added the class to json_field.services.yml
:
services: json_field.views: class: Drupaljson_fieldJSONViews json_field.normalizer.field.json_field: class: Drupaljson_fieldNormalizerJsonFieldNormalizer tags: - { name: normalizer, priority: 1 }
However, after rebuilding the cache and accessing some JSON fields via JSON:API, I don’t see anything in the logs, so it seems like the class is not being picked up.