I installed the latest dev release of the Metatag module and it caused errors on the jsonapi pages due to how metatags are normalized.
I created a patch for the metatag module, but it was proposed that the patch should live in this module.
- https://www.drupal.org/node/2636852#comment-12215100
So I think this should really be added to the jsonapi module, which should take care of normalizing its own known entities.
- https://www.drupal.org/node/2636852#comment-12215416
After exploring the \Normalizer\ classes within the jsonapi module, it seems that you are not supporting normalization for other contrib modules. So that led me to submitting my patch to the metatag module first.
Any guidance on how we should approach this would be great. I'm happy to refactor my patch so it applies to jsonapi if that is deemed the best approach.
Comments
Comment #2
wim leersThanks for reporting this, this confirms #2901253: Add normalization support for metatag module.
Comment #3
wim leersGah, I meant #2860350: Document why JSON API only supports @DataType-level normalizers of course. c/p fail, sorry.
Comment #4
adamzimmermann commented@Wim Leers ah, yes this is definitely related to that. There are subtle differences though that I want to make sure we address in some ticket. I don't care which one we lump it with.
A quick summary of the issue is as follows:
FieldNormalizerValueobject.FieldNormalizerValueobject.Drupal\metatag\Normalizer\MetatagNormalizerwill work with jsonapi.Depending on how the jsonapi refactor goes, it may handle normalization for the metatag field, but I doubt one of the core normalizer classes will work with the metatag data. If that is the case, the array that
MetatagNormalizerreturns will still cause an error. Perhaps the answer is that this is still something the jsonapi module needs to address by adding a normalizer for metatag fields, i.e. a class that declares the following:If that is the case, would that effort be a part of #2860350: Document why JSON API only supports @DataType-level normalizers? It seems that issue or more about removing the jsonapi custom overrides and using core.
In the metatag contrib case, the contrib module doesn't provide the needed mechanisms to normalize its data, at least without throwing errors. Should adding that normalizer be the responsibility of jsonapi or metatag? If it is the responsiblity of jsonapi, perhaps we do that in this ticket?
I would love to come to a consensus for how contrib module data normalization is handled, as I'm hoping to solidify a metadata API "contract" between Drupal and a headless front-end for my current project and others who will invariable need to do this also. My "hack/patch" in #2636852: Make Metatag fields available as JSON is working for now, but isn't ideal moving forward.
Hope this helps!
Comment #5
damienmckennaAs the lead maintainer of Metatag, I am interested in helping to resolve the problem but have no understanding of the best way to help fix it; if it'll take changes to the Metatag module that's a-ok with me :)
Comment #6
e0ipsoI'm not sure I understand how a normalizer can be format agnostic. A normalizer is inseparable of a format. You normalize to a format.
I'm pretty sure that if a normalizer decides to take precedence and respond to the reserved
api_jsonformat, then it should play by the rules in the JSON API module. This is because it will need to be put in a JSON API document output, and it needs to be valid JSON API format and follow the module expectations.Comment #7
e0ipsoCan you elaborate on that? From my point of view these two issues are not related. This one is caused by a normalizer from a separate contrib with high precedence acting on the
api_jsonformat. The other one is JSON API not picking up automatically the new core's normalizer.Comment #8
adamzimmermann commentedThe
Drupal\metatag\Normalizer\MetatagNormalizerclass doesn't declareprotected $format = ['the_target_format'];like other classes do, such asDrupal\metatag\Normalizer\MetatagHalNormalizer. However, both are registered as services with thenormalizertag in their definition.So perhaps "format agnostic" is the wrong way to describe, but that is how it appears to someone new to D8 normalization.
Comment #9
e0ipsoThat is the core of the problem. A normalizer changes the shape of data into a given format. Therefore
Drupal\metatag\Normalizer\MetatagHalNormalizershould not be greedy and should not respondTRUEinsupportsNormalizationwhen the$formatprovided in that call is set to'api_json'.Comment #10
hanoiiThat's really how core is setup, look at any normalizer in the core's serialization module. It's as if `json` is the default. It's how it is and it's not bad per se.. so there's really not an agnostic normalizer but rather a default, and that's always 'json'.
It's not MetatagHalNormalizer that's being greedy. What's happening is that there's also the regular Drupal\metatag\Normalizer\MetatagNormalizer which defaults to TRUE if no format is set to the normalizer, but that's only because it's based on Drupal\serialization\Normalizer (core). Which is the case in most core's normalizers.
See:
i.e. $this->format is not set.
I am not sure again what's the proper fix here. Also I haven't reviewed the fixes and comments on the mentioned core issue to assess if that will really fix the problem.
Comment #11
wim leers#6 + #8 + #9 + #10 are duplicating the discussion at #2860350-19: Document why JSON API only supports @DataType-level normalizers through #2860350-23: Document why JSON API only supports @DataType-level normalizers. It's really the same problem. Let's all discuss it there, so we don't have a fragmented discussion.