Problem/Motivation

ResourceFieldEnhancerInterface::getOutputJsonSchema() is called in field definition normalizers to decorate/change/enhance the json schema generated by schemata module (e.g., if you're using openapi_jsonapi)

Field enhancers for "attributes" (non-relationship fields) can generate a schema that is pretty well atomic/independent of the parent normalizer. For relationships, the definition is more complex (e.g., includes an enum for the referenced entity type name) and this data may vary based on, say, renamed json:api property names. See #3224754: Make schema normalizer overrides module-agnostic (support jsonapi_schema as well as Schemata/OpenAPI) for missing implementation of schema collection for relationship fields.

Steps to reproduce

Try to generate an appropriate JSON schema for a relationship field; it's very easy to clobber the parent normalizer's type definition, complete with enum array.

Proposed resolution

Refactor the json schema generation for field enhancers to merge the returned array into the parent's. Or, at least, pass the parent definition to the field enhancer and let it decide which keys to adjust/preserve/reject.

Remaining tasks

User interface changes

API changes

This is likely a breaking change.

Data model changes

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

bradjones1 created an issue. See original summary.

bradjones1’s picture

So I ran into this again today and it seems like there's a catch-22; in the case of all the contexts in which Extras calls ResourceFieldEnhancerInterface::getOutputJsonSchema(), we have the "normal" schema on hand prior to the enhancer getting involved. So we could in theory pass it to this method.

The problem is that when Shaper calls ::doUndoTransform(), it does so without any schema from Drupal. So it expects the enhancer to be able to provide a full schema without any other context. Speaking of context, to the extent that is provided it's not currently passed to ::getOutputJsonSchema(), either.

I suppose we could somehow stick the un-enhanced schema into like, the context and somehow flow that through? Feels janky, however.

It's just a bummer that you essentially have to re-create the schema within an enhancer even if you aren't changing the schema of the output.

e0ipso’s picture

I suppose we could somehow stick the un-enhanced schema into like, the context and somehow flow that through? Feels janky, however.

I think this is a good match for the context object. There are many variables at play that may be needed by the enhancer, it is impossible to anticipate. The context object is a fancy $options array.