Problem/Motivation
When attempting to use ?include for a related field that is not able to have its referenced types discerned in calculateRelatableResourceTypes and subsequently getRelatableResourceTypesFromFieldDefinition the request causes an error that is not intuitive. I'm not sure if this is something that JSON:API can/should guard against as it happened from another module. However it was a little jarring and took me a little while to understand what's happening, so at the very least I thought it'd be a good talking point.
To reproduce
- Include the dynamic entity reference module
- Add a dynamic entity reference field on a content type
- Make a request for the node with ?include=field_ref_dynamic
The error looks something like:
{
"title": "Bad Request",
"status": 400,
"detail": "`field_ref_dynamic` is not a valid relationship field name. Possible values: node_type, revision_uid, uid, menu_link, field_ref_dynamic."
}The confusions comes from; the field is not valid but you can use the field.
Proposed solution
In this specific example; getRelatableResourceTypesFromFieldDefinition target_type, handler_settings are both null so the settings of the field cannot be understood by the method. This results in the relatable resource types configuration array being empty for field_ref_dynamic. When resolving an include path in resolveInternalIncludePath it explicitly catches this and raises the error.
Perhaps the configuration array should be filtered of empty settings values before in calculateRelatableResourceTypes before the resolver.
Workaround
Use a core entity reference field.
Comments
Comment #2
wim leersThis is not a bug; DER simply doesn't have the necessary normalizer yet — it only has a HAL-specific normalizer (see #2844946: Add DynamicEntityReferenceItemNormalizer for serialization module).
Funny enough, this came up just yesterday in the API-First Initiative meeting: see #3027430: Dynamic Entity Reference normalization support.
Comment #3
wim leersSo, see you in #3027430: Dynamic Entity Reference normalization support :)
Comment #4
wim leers@steveworley just posted an amazing comment at #3027430-8: Dynamic Entity Reference normalization support, which led me to reopen this issue. This is what he wrote:
Comment #5
wim leersGah, Chromium ate my comment 😠
We'll need a failing regression test for this in
JsonApiRegressionTest.This appears to be the root cause.
I installed DER and created a field. Indeed,
target_typeis absent. Which makes sense, because the goal of DER is to allow it to be selected by the user. And\Drupal\jsonapi\ResourceType\ResourceTypeRepository::calculateRelatableResourceTypes()indeed assumes thattarget_typeexists (meaning only one entity type can be referenced), thus coupling it to core'sentity_referenceand preventing contrib'sdynamic_entity_reference.A DER field storage config has settings like this:
This allows
commentandnode. But if theexclude_entity_typesboolean is flipped from false to true, that is inverted. Fortunately,\Drupal\dynamic_entity_reference\Plugin\Field\FieldType\DynamicEntityReferenceItem::getTargetTypes($settings)exists so we don't need to duplicate all that logic.And the DER field config has settings like this:
Allowed target bundles must be selected.
The
target_typehandling obviously is very different in DER, but thetarget_bundleshandling is similar.Ideally, both ER and DER would provide a standardized way to get this information. I am concerned that doing this makes it impossible for JSON:API to go into core since it'd be calling a contrib module's API.
Perhaps the appropriate solution for now is to do this instead:
Comment #6
wim leersThis issue is about DER support minus the normalization support (that is covered by #3027430: Dynamic Entity Reference normalization support).
Comment #7
jibranI happy to have an interim fix in DER.
Comment #8
gabesullice@jibran, does DER have any configurable constraints for the referenceable type? Or is it completely determined by the field value?
I'm just thinking about a future when JSON:API wants to have much better schema support and I'm curious if we'll be able to find out what types are potentially referenced in advance.
Comment #9
wim leersI made the connection to this issue in #3005274-17: [PP-1] Support for Paragraphs' ability to negate the entity reference selection.
Comment #10
jibranComment #11
wim leers#8 needs feedback from @jibran.
Comment #12
wim leersPostponing this on #3057545: ResourceTypeRepository wrongly assumes that all entity reference fields have the setting "target_type", see #3057545-7: ResourceTypeRepository wrongly assumes that all entity reference fields have the setting "target_type".
Comment #13
jibranThere is a constraint \Drupal\dynamic_entity_reference\Plugin\Validation\Constraint\ValidDynamicReferenceConstraintValidator and it is using field settings to determine the valid reference.
Does it answer your question?
Comment #14
wim leersComment #20
smustgrave commentedBeen in PNMI for 4 years so safe to say it can be closed out I believe.
If still a valid feature request please reopen updating issue summary for how it pertains to D10
Thanks!
Comment #21
bbrala#3057545: ResourceTypeRepository wrongly assumes that all entity reference fields have the setting "target_type" has been committed.