Problem/Motivation
JSON:API recently implemented #3022584: Consolidate and simplify NormalizerValue objects: introduce CacheableNormalization. Right now, the major issue with the whole serialization system is that it doesn't return the cacheablity metadata. Any external app which wants to relay on Drupal cacheablity metadata to cache the response on the client side cannot do it, if one want to expose the cacheablity metadata. Even in Drupal to cache the response JSON:API has to jump so many hoops see the patch committed in #3022584: Consolidate and simplify NormalizerValue objects: introduce CacheableNormalization.
Proposed resolution
Introduce new CacheableNormalization domain object so that every Normalizer can return the cacheablity metadata and entities can bubble appropriate cacheablity metadata.
Something like
class CacheableNormalization implements CacheableDependencyInterface {
use CacheableDependencyTrait;
/**
* A normalized value.
*
* @var mixed
*/
protected $normalization;
Remaining tasks
To preseve the BC just like $return_as_object in \Drupal\Core\Access\AccessibleInterface::access($operation, AccountInterface $account = NULL, $return_as_object = FALSE) $context['return_as_object'] can be used in \Symfony\Component\Serializer\Normalizer\NormalizerInterface::normalize($object, $format = null, array $context = array()) to return CacheableNormalization object.
OR
CacheableNormalization can implement __toString or ArrayAccess to only return Normalized value.
User interface changes
None
API changes
Hopefully, none.
Data model changes
TBD
Release notes snippet
TBD
Comments
Comment #2
jibranImplementing this issue will also fix the issues like #2997123: Cacheability of normalized computed fields' properties is not captured during serialization
Comment #3
wim leersAs much as I'd like to see this happen, I'm not very optimistic about the BC aspects of this. In either solution you propose, we need pretty much every normalizer in core and contrib to implement that fallback logic. 😔
And perhaps even more importantly: it violates
\Symfony\Component\Serializer\Normalizer\NormalizerInterface::normalize().Comment #4
gabesulliceThe solution I explored for this in the JSON:API issue was to not have every normalizer be able to return a
CacheableNormalization, but instead allow the serializer "upcast" raw normalizations. Then, various normalizers could start to 'opt-in' and the serializer could skip the wrapping step.I'm sure there are problems to solve there, but it might get something rolling.
Comment #5
wim leersWe talked about this yesterday during the API-First meeting. @gabesullice explained his idea in more detail: where essentially the
serializerservice inspects each normalizer service's service tags, and if they indicate that they're returningCacheableNormalizationobjects, the serializer service will handle any transformations necessary to let different normalizers collaborate like they do today.@jibran, is that sufficient, or would you like us to explain this in more detail?
Comment #6
gabesulliceThinking about it more, I don't think any interfaces or service tags are actually necessary. I think it could work a bit like this:
Comment #16
fpoirier commented+1