I found a workaround to prevent this from happening, until graphql updates to v15.
I debugged this and it turns out it is (or more was) a bug in webonyx/graphql-php: https://github.com/webonyx/graphql-php/pull/1194
It happens because it tries to resolve our "File" type. This code:
elseif (is_callable($typeCandidate) {
Because is_callable("File") will return true, it then later on calls file(), which leads to the error here.
This seems to have been fixed already for quite some time, but the Drupal graphql Module still uses v14 of the library. There seems to be work going on to update to v15. Until then, I'll have to see what I can do to prevent this from happening.
I was able to add rudimentary support for this specific field type, even if its data definitions are broken. Because we don't (yet) support union types, the type of the field is always going to be "Entity".
I looked into this. There are two problems here:
First, the dynamic_entity_reference module has a broken annotation, as already spotted in #6:
https://git.drupalcode.org/project/dynamic_entity_reference/-/blob/3.x/s...
This should be fixed in the module itself, because the same error will happen every time one tries to load the definition of this data type.
Second, even if this is fixed, there is this code in core that gets called when trying to get the definition for the "dynamic_entity_reference" data type: https://git.drupalcode.org/project/drupal/-/blob/11.x/core/lib/Drupal/Co...
This is the class that the DataDynamicReferenceDefinition class extends from. The method will remove the "_reference" from the string and then call ::create with "dynamic_entity", which is not a valid plugin ID.
Because the schema builder tries to figure out the best possible type for an entity reference field, it tries to get the definitions of fields and items. That way a "field_image" results in a field in GraphQL with type "MediaImage", instead of a generic "Entity" interface.
I'll see if it's possible to work around these issues in the schema builder.
Yeah exactly, it's quite tricky to fix. I guess prefixing it with "coreSchemaNumber_" would be the safest (since its very unlikely to clash with anything else). But it's quite verbose. I think "GQL_ENUM_" could also work, it's a bit shorter. What do you think?
dulnan β made their first commit to this issueβs fork.
Tested it on a large project and fixed a bug where types for disabled bundles were generated for entity_reference field types. Works very well! I was able to reduce the schema size significantly, thanks!
dulnan β made their first commit to this issueβs fork.
dulnan β made their first commit to this issueβs fork.
pfrenssen β credited dulnan β .
pfrenssen β credited dulnan β .
pfrenssen β credited dulnan β .
pfrenssen β credited dulnan β .
pfrenssen β credited dulnan β .
dulnan β created an issue.
pfrenssen β credited dulnan β .
pfrenssen β credited dulnan β .
pfrenssen β credited dulnan β .
pfrenssen β credited dulnan β .
pfrenssen β credited dulnan β .
pfrenssen β credited dulnan β .
pfrenssen β credited dulnan β .
pfrenssen β credited dulnan β .
pfrenssen β credited dulnan β .
dasjo β credited dulnan β .
pfrenssen β credited dulnan β .
There is currently a "hidden" feature that does not generate entity reference fields (even if they're enabled), if the field references an entity type that is not enabled in your schema. In your case, if the picture field on the user is a reference to a media, then you'll also have to enable the media entity type. Could you check if this is the case?
I've created a new release that includes the new image extension.
Thanks for the fix, I had to add a check to either use the entity or entity_revision buffer based on if the entity type is revisionable. The entityQuery should now work as expected.
dulnan β made their first commit to this issueβs fork.
I think the issue comes from the fact that the language-url negotiator is not enabled in a single-language setup, but the data producer still tries to get an instance of it. While this works even if the negotiator is not enabled, it seems that, because it has not been initialized properly by Drupal, the $currentUser on the instance is NULL.
I have added a check to see if the language-url method is enabled before getting the instance. I think this will also resolve the issue.
The problem was that the base schema only declared the Url interface and doesn't provide an actual type that implements it. The routing extension implements these types.
I have added a new type called DefaultUrl to the base schema, that implements the Url interface. This makes it possible to use the schema without the routing extension.
This is indeed a problem. It will also result in problems when there is both a field "field_a_1" and "field_a1" on the same entity.
But as a fix for the resolver I will pass along the actual field name inside the GraphQL field description and extract it in the resolver. That way it only has to do the conversion from camel to snake when the original field name could not be extracted from the description.
As a nice side effect it should also help making it easier finding fields in the schema using the Drupal machine name.
I gave this a try and it was pretty straight forward. I didn't want to make it work like in V3, because that created tons of overly specific fields (I counted 460 fields in one of our projects still using V3...)
Instead there is only a single field added to each entity type called *reverseReferences*. It returns a type called *ReverseReferenceContext* where a field *query* is available. This query field takes a parameter called *referenceFields*, where one can specify which fields should be used to look for references. This also allows to create reusable fragments for such reverse lookups.
query {
entityById(entityType: TAXONOMY_TERM, id: 123) {
reverseReferences {
...reverseOfficeLookup
}
}
}
fragment reverseOfficeLookup on ReverseReferenceContext {
query(
referenceFields: ["field_office"]
entityType: NODE
filter: {
conditions: [
{ field: "type", value: "news_story" }
{ field: "status", value: "1" }
{ field: "field_featured", value: "1" }
]
}
sort: { field: "created", direction: DESC }
limit: 2
) {
entities: items {
id
}
}
}
This new schema extension is available in the dev branch.
I have implemented a new "Image" extension that adds a derivative field. It works pretty much like in graphql v3:
query {
entityById(entityType: MEDIA, id: "3") {
... on MediaImage {
fieldImage {
hero: derivative(style: HERO) {
urlPath
width
height
}
thumbnail: derivative(style: THUMBNAIL) {
urlPath
width
height
}
}
}
}
}
The new extension is available on the dev branch.
This is now fixed. Schema extensions can now check which GraphQL types are available and can only extend ones that are available. This solves the issue here, where the FieldItemTypeDatetime might not exist.
I have fixed this (and other similar issues). They happened because by default, if no extensions are enabled, there are no fields on the Query type. This results in the following (invalid) schema:
type Schema {
query: Query
}
type Query
The module now implements a ping query and mutation by default, so that it's not possible anymore to generate a schema with empty Query or Mutation types.
I've created a menu link entity with an external URL and inspected it when the external field is resolved:
The value is actually FALSE in the MenuLinkContent entity. So this seems to be a core bug.
As a workaround you can get the same information by accessing uri in the link field and checking the __typename of the URL, which will be ExternalUrl.
query {
entityById(entityType: MENU, id: "test") {
... on Menu {
links {
link {
content {
... on MenuLinkContentTest {
label
link {
uri {
__typename
}
}
}
}
}
}
}
}
}
You're correct, there are only two generic fields for entity queries. The reason is that this module supports all entity types out of the box and deriving two fields for each entity type adds a lot of duplication to the schema.
However, currently all enabled entity types are also automatically available to be queried directly. This is not ideal and I'm planning to add entity type specific query fields again, but so that one can select which ones should be generated.
Regarding the entityById for menus: The menu entity is not an instance of TranslatableInterface, which is why the langcode argument is ignored because no translation can be loaded. This also means all subsequent fields will resolve based on the default langcode of the menu entity. However, if you perform the GraphQL request already in the desired language (e.g. by using /en/graphql as the URL) you will get both the menu and the links in EN.
Alternatively, if you want to fetch both NL and EN in the same query, you can instead get the translation of the MenuLinkContent entity:
query {
entityById(entityType: MENU, id: "main") {
... on Menu {
links {
link {
content {
... on MenuLinkContentMain {
en: translation(langcode: EN) {
label
}
nl: translation(langcode: NL) {
label
}
}
}
}
}
}
}
}
Please note that there is a bug (actually it's by design) in the drupal/graphql module when requesting a translation that does not exist: https://github.com/drupal-graphql/graphql/pull/1176
I plan to add a workaround by returning NULL in this case, in order to not produce internal server errors for such trivial actions.
dulnan β made their first commit to this issueβs fork.