Problem/Motivation
While trying to figure out how to have json api display the value of a entity reference field as an embedded json document,
i tried to use the Advanced Enhancer feature of jsonapi_extras and changed the config of my ent_ref field with:
Enhancer for: field_my_ent_ref > [ JSON Field ]
and then when querying the content over json api, it bombed out with this unhandled exception 500 error:
TypeError: json_decode(): Argument #1 ($json) must be of type string, array given in json_decode() (line 26 of /var/app/current/web/core/lib/Drupal/Component/Serialization/Json.php)
#0 /var/app/current/web/core/lib/Drupal/Component/Serialization/Json.php(26): json_decode(Array, true)
#1 /var/app/current/web/modules/contrib/jsonapi_extras/src/Plugin/jsonapi/FieldEnhancer/JSONFieldEnhancer.php(64): Drupal\Component\Serialization\Json::decode(Array)
#2 /var/app/current/vendor/e0ipso/shaper/src/DataAdaptor/DataAdaptorTransformerTrait.php(57): Drupal\jsonapi_extras\Plugin\jsonapi\FieldEnhancer\JSONFieldEnhancer->doUndoTransform(Array, Object(Shaper\Util\Context))
#3 /var/app/current/web/modules/contrib/jsonapi_extras/src/Normalizer/ResourceIdentifierNormalizer.php(73): Drupal\jsonapi_extras\Plugin\ResourceFieldEnhancerBase->undoTransform(Array, Object(Shaper\Util\Context))
#4 /var/app/current/vendor/symfony/serializer/Serializer.php(153): Drupal\jsonapi_extras\Normalizer\ResourceIdentifierNormalizer->normalize(Object(Drupal\jsonapi\JsonApiResource\ResourceIdentifier), 'api_json', Object(Shaper\Util\Context))
#5 /var/app/current/web/core/modules/jsonapi/src/Serializer/Serializer.php(62): Symfony\Component\Serializer\Serializer->normalize(Object(Drupal\jsonapi\JsonApiResource\ResourceIdentifier), 'api_json', Array)
#6 /var/app/current/web/core/modules/jsonapi/src/Normalizer/DataNormalizer.php(26): Drupal\jsonapi\Serializer\Serializer->normalize(Object(Drupal\jsonapi\JsonApiResource\ResourceIdentifier), 'api_json', Array)
#7 [internal function]: Drupal\jsonapi\Normalizer\DataNormalizer->Drupal\jsonapi\Normalizer\{closure}(Object(Drupal\jsonapi\JsonApiResource\ResourceIdentifier))
#8 /var/app/current/web/core/modules/jsonapi/src/Normalizer/DataNormalizer.php(27): array_map(Object(Closure), Array)
#9 /var/app/current/vendor/symfony/serializer/Serializer.php(153): Drupal\jsonapi\Normalizer\DataNormalizer->normalize(Object(Drupal\jsonapi\JsonApiResource\RelationshipData), 'api_json', Array)
#10 /var/app/current/web/core/modules/jsonapi/src/Serializer/Serializer.php(62): Symfony\Component\Serializer\Serializer->normalize(Object(Drupal\jsonapi\JsonApiResource\RelationshipData), 'api_json', Array)
#11 /var/app/current/web/core/modules/jsonapi/src/Normalizer/RelationshipNormalizer.php(26): Drupal\jsonapi\Serializer\Serializer->normalize(Object(Drupal\jsonapi\JsonApiResource\RelationshipData), 'api_json', Array)
#12 /var/app/current/vendor/symfony/serializer/Serializer.php(153): Drupal\jsonapi\Normalizer\RelationshipNormalizer->normalize(Object(Drupal\jsonapi\JsonApiResource\Relationship), 'api_json', Array)
#13 /var/app/current/web/core/modules/jsonapi/src/Serializer/Serializer.php(62): Symfony\Component\Serializer\Serializer->normalize(Object(Drupal\jsonapi\JsonApiResource\Relationship), 'api_json', Array)
#14 /var/app/current/web/core/modules/jsonapi/src/Normalizer/ResourceObjectNormalizer.php(183): Drupal\jsonapi\Serializer\Serializer->normalize(Object(Drupal\jsonapi\JsonApiResource\Relationship), 'api_json', Array)
#15 /var/app/current/web/core/modules/jsonapi/src/Normalizer/ResourceObjectNormalizer.php(121): Drupal\jsonapi\Normalizer\ResourceObjectNormalizer->serializeField(Object(Drupal\Core\Field\EntityReferenceFieldItemList), Array, 'api_json')
#16 /var/app/current/web/core/modules/jsonapi/src/Normalizer/ResourceObjectNormalizer.php(73): Drupal\jsonapi\Normalizer\ResourceObjectNormalizer->getNormalization(Array, Object(Drupal\jsonapi\JsonApiResource\ResourceObject), 'api_json', Array)
#17 /var/app/current/web/modules/contrib/jsonapi_extras/src/Normalizer/JsonApiNormalizerDecoratorBase.php(38): Drupal\jsonapi\Normalizer\ResourceObjectNormalizer->normalize(Object(Drupal\jsonapi\JsonApiResource\ResourceObject), 'api_json', Array)
#18 /var/app/current/web/modules/contrib/jsonapi_extras/src/Normalizer/ResourceObjectNormalizer.php(24): Drupal\jsonapi_extras\Normalizer\JsonApiNormalizerDecoratorBase->normalize(Object(Drupal\jsonapi\JsonApiResource\ResourceObject), 'api_json', Array)
#19 /var/app/current/vendor/symfony/serializer/Serializer.php(153): Drupal\jsonapi_extras\Normalizer\ResourceObjectNormalizer->normalize(Object(Drupal\jsonapi\JsonApiResource\ResourceObject), 'api_json', Array)
#20 /var/app/current/web/core/modules/jsonapi/src/Serializer/Serializer.php(62): Symfony\Component\Serializer\Serializer->normalize(Object(Drupal\jsonapi\JsonApiResource\ResourceObject), 'api_json', Array)
#21 /var/app/current/web/core/modules/jsonapi/src/Normalizer/DataNormalizer.php(26): Drupal\jsonapi\Serializer\Serializer->normalize(Object(Drupal\jsonapi\JsonApiResource\ResourceObject), 'api_json', Array)
#22 [internal function]: Drupal\jsonapi\Normalizer\DataNormalizer->Drupal\jsonapi\Normalizer\{closure}(Object(Drupal\jsonapi\JsonApiResource\ResourceObject))
#23 /var/app/current/web/core/modules/jsonapi/src/Normalizer/DataNormalizer.php(27): array_map(Object(Closure), Array)
#24 /var/app/current/vendor/symfony/serializer/Serializer.php(153): Drupal\jsonapi\Normalizer\DataNormalizer->normalize(Object(Drupal\jsonapi\JsonApiResource\ResourceObjectData), 'api_json', Array)
#25 /var/app/current/web/core/modules/jsonapi/src/Serializer/Serializer.php(62): Symfony\Component\Serializer\Serializer->normalize(Object(Drupal\jsonapi\JsonApiResource\ResourceObjectData), 'api_json', Array)
#26 /var/app/current/web/core/modules/jsonapi/src/Normalizer/JsonApiDocumentTopLevelNormalizer.php(193): Drupal\jsonapi\Serializer\Serializer->normalize(Object(Drupal\jsonapi\JsonApiResource\ResourceObjectData), 'api_json', Array)
#27 /var/app/current/vendor/symfony/serializer/Serializer.php(153): Drupal\jsonapi\Normalizer\JsonApiDocumentTopLevelNormalizer->normalize(Object(Drupal\jsonapi\JsonApiResource\JsonApiDocumentTopLevel), 'api_json', Array)
#28 /var/app/current/web/core/modules/jsonapi/src/Serializer/Serializer.php(62): Symfony\Component\Serializer\Serializer->normalize(Object(Drupal\jsonapi\JsonApiResource\JsonApiDocumentTopLevel), 'api_json', Array)
#29 /var/app/current/web/core/modules/jsonapi/src/EventSubscriber/ResourceResponseSubscriber.php(120): Drupal\jsonapi\Serializer\Serializer->normalize(Object(Drupal\jsonapi\JsonApiResource\JsonApiDocumentTopLevel), 'api_json', Array)
#30 /var/app/current/web/core/modules/jsonapi/src/EventSubscriber/ResourceResponseSubscriber.php(85): Drupal\jsonapi\EventSubscriber\ResourceResponseSubscriber->renderResponseBody(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\jsonapi\CacheableResourceResponse), Object(Drupal\jsonapi\Serializer\Serializer), 'api_json')
#31 [internal function]: Drupal\jsonapi\EventSubscriber\ResourceResponseSubscriber->onResponse(Object(Symfony\Component\HttpKernel\Event\ResponseEvent), 'kernel.response', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
#32 /var/app/current/web/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php(142): call_user_func(Array, Object(Symfony\Component\HttpKernel\Event\ResponseEvent), 'kernel.response', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
#33 /var/app/current/vendor/symfony/http-kernel/HttpKernel.php(202): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object(Symfony\Component\HttpKernel\Event\ResponseEvent), 'kernel.response')
#34 /var/app/current/vendor/symfony/http-kernel/HttpKernel.php(190): Symfony\Component\HttpKernel\HttpKernel->filterResponse(Object(Drupal\jsonapi\CacheableResourceResponse), Object(Symfony\Component\HttpFoundation\Request), 1)
#35 /var/app/current/vendor/symfony/http-kernel/HttpKernel.php(81): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#36 /var/app/current/web/core/lib/Drupal/Core/StackMiddleware/Session.php(58): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#37 /var/app/current/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#38 /var/app/current/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#39 /var/app/current/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#40 /var/app/current/web/modules/contrib/webform_product/src/RedirectMiddleware.php(42): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#41 /var/app/current/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\webform_product\RedirectMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#42 /var/app/current/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#43 /var/app/current/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#44 /var/app/current/web/core/lib/Drupal/Core/DrupalKernel.php(709): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#45 /var/app/current/web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#46 {main}
.
Steps to reproduce
Create a content type with an entity reference field to another content type.
Use the Advanced Enhancer feature of jsonapi_extras and change the config of your ent_ref field with:
Enhancer for: field_your_ent_ref > [ JSON Field ]
Proposed resolution
Fix jsonapi to allow to display the value of an ent_ref field as a nested json document easily
Remaining tasks
User interface changes
API changes
Data model changes