[META] Normalization System: clean up/speed up/provide schema

Created on 27 December 2018, almost 6 years ago
Updated 9 October 2023, about 1 year ago

Over the past year, we've added comprehensive test coverage and ensured that JSON:API was both secure and cacheable (by auditing and correcting cache contexts/tags)

In this process, we learned that our normalizers were incompatible with the Symfony normalizer interface and we "cordoned off" the normalization system with the eventual intent of refactoring it and adding support for schema generation/validation.

This issue is meant to track and coordinate that process. Below, I've written out in broad strokes the steps, in order, that I think we can take to end up in a world where our normalizers aren't a black box to outsiders, where they're faster, where they're schema-complete and where there's a clear path forward for bringing Drupal core's normalizers into that fast/schema-complete world too (with minimal disruption and no BC-breaks).

  1. (Done in #3252872: Use CacheableSupportsMethodInterface for performance improvement in normalizers β†’ ) Following up on that, I think we could use reflection to identify TypedData normalizers (IOW, non-JSON:API normalizers) that can also be cached and use that knowledge to alter their service definitions in order to add the "deterministic" tag.
  2. - No longer a need for deterministic tag.
  3. I'd like to add two new interfaces called SchematicNormalizerInterface and SchematicDenormalizerInterface. These interfaces would have a get(De)NormalizationSchema method on them. JSON:API could enforce this interface for its own normalizers and begin adding it to core normalizers as well. With the addition of that interface, we could then validate input and output of those normalizers against their declared schema. The challenge here is that normalizers for things like EntityInterface can't really provide a useful schema without knowledge of the entity type/bundle This is where @e0ipso's ResourceFieldInterface et al. come into play by allowing the ResourceType to know about its field types. I think this could work and perhaps the new schema interface will have to take a queue from (or import) @e0ipso's shaper library with its concept of normalization "context" (this is different from Symfony's idea of context, I believe).
  4. Paired with the schema interfaces, we'd then have enough knowledge to generate resource type-level schema's with some certainty. Contrib and core would have a BC-compliant way of opting in to this system by implementing the additional interface(s).
  5. With this concept proven, I think we could then require new normalizers to have this tag and interface on them and move those tags/interfaces into Drupal core. When normalizers are detected without either of them, we could throw deprecation notices and then require that they be implemented in Drupal 11.
  6. After (or maybe even before) these deprecations, I think that we could have a schema generation module that outputs a schema with schemas, if known, or any or some other safe default in other cases.

Obviously, the above is subject to lots of input and suggestions. I've been thinking about all this for a while but have never actually put it all down in one place.

🌱 Plan
Status

Active

Version

11.0 πŸ”₯

Component
JSON APIΒ  β†’

Last updated 7 days ago

Created by

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡ΊπŸ‡ΈUnited States bradjones1 Digital Nomad Life
  • πŸ‡ΊπŸ‡ΈUnited States bradjones1 Digital Nomad Life

    Updated the IS. I _think_ the answer to #16 is no, it's no longer relevant, however I pinged @bbrala for his updated thinking since he was the last to comment on #3014283-47: Use ResourceTypeFields to statically determine the field normalizer β†’ .

    Much of the IS update I made was to trim out all the extra work that would have been required to do our own implementation of the cacheable-supports logic that we got from Symfony upstream. The challenge with this issue is that it's been open so long, a lot of the underlying landscape has shifted a bit. Again, I _think_ this basically means we can start at what Gabe originally proposed as his #5, or ✨ Generate JSON schema for content entity types Needs review . More specifically, we can tackle only the normalization side right now, since that's what the majority of schema generation is really focused on, and then perhaps tackle denormalization schema as a follow-on which would allow us to express different schemas for different HTTP verbs, e.g. in OpenAPI specs.

Production build 0.71.5 2024