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

steveworley created an issue. See original summary.

wim leers’s picture

Status: Active » Closed (duplicate)
Issue tags: +API-First Initiative
Related issues: +#2844946: Add DynamicEntityReferenceItemNormalizer for serialization module

This 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.

wim leers’s picture

wim leers’s picture

Status: Closed (duplicate) » Active

@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:

Thanks for pointing this out @wim.

I understand that its just a normaliser that isn't picking this up and serialising correctly, I still think the modules implementation for discerning these fields might be too greedy given the error I was receiving. For reference the error is:

"detail": "`field_ref_dynamic` is not a valid relationship field name. Possible values: field_ref_dynamic."

When including a DER field the output says that you should be able to use the field. All you would need to do to replicate this is:

- Define a field that extends DataReferenceTargetDefinition
- Don't add target_type in the field

This triggers the following flow:

- getRelatableResourceTypesByField will return your field but it will be an empty array
- resolveInternalIncludePath checks to see if the key returned is empty

I think it's just a case that getRelatableResourceTypesByField should do more checking and resolveInternalIncludePath should maybe rely on the getRelatableResourceTypesByField to check for the field. If my field doesn't have the right configuration it shouldn't show that I can request it.

wim leers’s picture

Issue tags: +Needs tests

Gah, Chromium ate my comment 😠

We'll need a failing regression test for this in JsonApiRegressionTest.

target_type, handler_settings are both null so the settings of the field cannot be understood by the method.

This appears to be the root cause.


I installed DER and created a field. Indeed, target_type is 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 that target_type exists (meaning only one entity type can be referenced), thus coupling it to core's entity_reference and preventing contrib's dynamic_entity_reference.

A DER field storage config has settings like this:

settings:
  exclude_entity_types: false
  entity_type_ids:
    comment: comment
    node: node

This allows comment and node. But if the exclude_entity_types boolean 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:

settings:
  comment:
    handler: 'default:comment'
    handler_settings:
      target_bundles:
        comment: comment
      sort:
        field: _none
      auto_create: false
      auto_create_bundle: ''
  node:
    handler: 'default:node'
    handler_settings:
      target_bundles:
        article: article
        page: page
      sort:
        field: _none
      auto_create: false
      auto_create_bundle: article

Allowed target bundles must be selected.


The target_type handling obviously is very different in DER, but the target_bundles handling 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:

If my field doesn't have the right configuration it shouldn't show that I can request it.

wim leers’s picture

Title: calculateRelatableResourceTypes incorrectly suggests fields that can't be used » Dynamic Entity Reference: support discovering relatable resource types
Category: Bug report » Feature request
Priority: Minor » Normal

This issue is about DER support minus the normalization support (that is covered by #3027430: Dynamic Entity Reference normalization support).

jibran’s picture

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.

I happy to have an interim fix in DER.

gabesullice’s picture

@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.

wim leers’s picture

jibran’s picture

Issue tags: +DER issue
wim leers’s picture

Status: Active » Postponed (maintainer needs more info)

#8 needs feedback from @jibran.

wim leers’s picture

Title: Dynamic Entity Reference: support discovering relatable resource types » [PP-1] Dynamic Entity Reference: support discovering relatable resource types
jibran’s picture

does DER have any configurable constraints for the referenceable type? Or is it completely determined by the field value?

There 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?

wim leers’s picture

Project: JSON:API » Drupal core
Version: 8.x-2.x-dev » 8.8.x-dev
Component: Code » jsonapi.module

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Status: Postponed (maintainer needs more info) » Closed (outdated)
Issue tags: -

Been 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!

bbrala’s picture

Title: [PP-1] Dynamic Entity Reference: support discovering relatable resource types » Dynamic Entity Reference: support discovering relatable resource types