I got more clarity on this after my original post, so I'm adding the TL/DR version here:
Steps to recreate:
- Drupal site (try Standard profile) using jsonapi and jsonapi_extras
- Node type with an entityreference field (built-in with Standard profile: article + tags)
- In jsonapi_extras config, override the node type and change the "alias" of the entityreference field to something else (eg, from "field_tags" to just "tags")
- In jsonapi_extras config, override the referenced entity/bundle and change the "resource type" to something else (eg, from "taxonomy_term--tags" to just "tags")
- Create a node, referencing an entity through this field (ie, create a tag term and then an article referencing that tag)
- Delete the referenced entity (the tag)
- Try a jsonapi query that would grab the node, along with the referenced entity (eg: /jsonapi/node/article?include=tags&fields[node--article]=title,tags&fields[tags]=name)
- See the AssertionError mentioned below
Proposed solution:
When a referenced entity is missing/null, getRelatableResourceTypesByField is being called with $field->getName(), which is always the resource's internal name. So in the attached patch I'm explicitly converting that to the resource's public name.
Original post follows:
---
I don't know whether this is a bug with this module, or a bug with my site, or simply a support request. Apologies for my ignorance here, but you gotta start somewhere right? Either way I could use some help here:
First here are my versions:
- jsonapi: in core, Drupal 8.7.3
- jsonapi_extras: 3.8.0
I am requesting data with this URL: /api/agency_components?fields[agency_component]=title,agency,submission_address,submission_fax,website,foia_officers,public_liaisons,service_centers&fields[agency]=name&fields[foia_officers]=name,title,email,phone&fields[public_liaisons]=name,title,email,phone&fields[service_centers]=name,title,email,phone&include=agency,foia_officers,public_liaisons,service_centers&page[limit]=50
I am getting this error:
AssertionError: assert(is_string($resource_type) || $resource_type instanceof ResourceType) in assert() (line 81 of core/modules/jsonapi/src/JsonApiResource/ResourceIdentifier.php).
From some xdebugging it seems like this is resulting from an empty array being returned by getRelatableResourceTypesByField. The getRelatableResourceTypes method returns an array of field names that have been customized by this module. For example, instead of "field_service_centers" it has "service_centers". But $field_name, at this point in the code, is 'field_service_centers'. This means that isset($relatable_resource_types[$field_name]) is always false when it runs on a field that has had its name customized by this module.
Hope that makes sense. Please let me know if you think this is due to a quirk or misconfiguration in my site, and I will try to recreate with a blank slate Drupal site. Thank you!
| Comment | File | Size | Author |
|---|---|---|---|
| #11 | Screenshot at Sep 17 23-52-48.png | 117.43 KB | phthlaap |
| #11 | Screenshot at Sep 17 23-47-12.png | 353.17 KB | phthlaap |
| #9 | jsonapi-extras-issue.mov | 23.77 MB | phthlaap |
| #3 | drupal--jsonapi--3063326--public-name-for-relatable-fields.patch | 991 bytes | brockfanning |
Comments
Comment #2
brockfanning commentedPlease hold off on investigating here - I think there is some more investigation I can do on my end.
Comment #3
brockfanning commentedAfter some more digging I think this probably belongs in the jsonapi queue (or I guess Drupal core now?). I'm moving it over and attaching a patch that fixes it for me. I think the problem was that, when a referenced entity is missing/null, getRelatableResourceTypesByField is being called with $field->getName(), which is always the resource's internal name. So in the attached patch I'm explicitly converting that to the resource's public name.
Comment #4
brockfanning commentedComment #5
brockfanning commentedComment #6
brockfanning commentedComment #7
brockfanning commentedComment #8
wim leersNice find!
This still needs tests. You can find an example of an alias-related test at
\Drupal\Tests\jsonapi\Functional\JsonApiRegressionTest::testDenormalizeAliasedRelationshipFromIssue2953207(). I suggest copy/pasting that test method and modifying it to match your scenario :)Comment #9
phthlaap commentedCould you please refer my screencast, is it related to this issue?
Comment #10
wim leers#9: Yes, those are exactly the steps that @brockfanning provided in the issue summary.
Could you perhaps write that failing test that I asked for in #8? 😊🙏
Comment #11
phthlaap commentedHi Wim,
After some hours try to write automated tests, I think this issue not belong to the relationship between entity.
Could you please take a look my screenshot?
When I get all resource type with the code below:
Because JSON:API Extras has override that service then I see the key of tags resource has been changed by JSON:API Extras:


So I cannot get a resource by entity type id and bundle:
$resource_type_repository->get('taxonomy_term', 'tags');That is reason the AssertError happen. Please help to suggest the solution or JSON:API Extra need disabled edit for resource type field.
Comment #13
brockfanning commentedI just get a working test written (5 months later...) and then noticed that this same fix has already gone into 8.8, with #3034786: ResourceIdentifier::getVirtualOrMissingResourceIdentifier() ignores field aliases; causes $relatable_resource_types field to be empty and results in an error. So I believe this can be closed, since we're only a few weeks away from 8.8 being released. I'm happy to continue using this patch until then, and will go ahead and close this.
@phthlaap: I think your problem may be different. I might have missed it, but in watching your screencast I didn't see you deleting any entities. Having a missing/deleted referenced entity is critical to recreating the problem this issue was about.