New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DX: Can't narrow down interface subtypes on an implementing object with register_graphql_field()
#3096
Comments
Basic Reproduction:The following code registers the The field types are changed on the
add_action( 'graphql_register_types', static function() {
// The graphql interface whose fields we'll narrow.
register_graphql_interface_type(
'NodeWithMyCustomContentNode',
[
'fields' => [
'childFieldOverloaded' => [
'type' => 'ContentNode',
'description' => __( 'This will be narrowed with graphql_register_field()', 'my-text-domain' ),
'resolveType' => static fn ( $source ) => isset( $source->post_type ) ? graphql_format_type_name( $source->post_type ) : null,
'resolve' => static fn ( $source ) => $source,
],
'childFieldFiltered' => [
'type' => 'ContentNode',
'description' => __( 'This will be narrowed with the filter directly', 'my-text-domain' ),
'resolveType' => static fn ( $source ) => isset( $source->post_type ) ? graphql_format_type_name( $source->post_type ) : null,
'resolve' => static fn ( $source ) => $source,
],
],
]
);
// Register the interface to all ContentNodes types.
register_graphql_interfaces_to_types( 'NodeWithMyCustomContentNode', [ 'ContentNode' ] );
// ✖️ Narrow down the type for Post Objects using `register_graphql_field()`
register_graphql_field(
'Post',
'childFieldOverloaded',
[
'type' => 'Post',
]
);
// ✔️ Use the `graphql_$type_name_fields` filter instead
add_filter(
'graphql_post_fields',
static function ( array $fields ) {
if ( isset( $fields['childFieldFiltered'] ) ) {
$fields['childFieldFiltered']['type'] = 'Post';
}
return $fields;
},
10,
2
);
},
); Then inspect the types or try the following query: {
posts {
nodes {
childFieldOverloaded {
title # Doesnt exist on ContentNode
... on Post {
title
}
}
childFieldFiltered {
title # Type type is a post so it works.
... on Post {
title
}
}
}
}
} ResultsAs you can see below, |
(Fun quirk with the filter workaround: seems to be a lifecycle issue where narrowing a field on an interface ( E.g. |
Description
When using
register_graphql_field()
, aDUPLICATE_FIELD
error is thrown even if the field being registered is compatible with the existing one.For example, let's say a
NodeWithSeo
interface registers theseo: SeoInterface
field. I should be able to overwritePostObject.seo
to be typePostObjectSeo implements SeoInterface
. However, because at this point in the lifecycle, the interface fields are already merged with the fields inWPObjectType
, the blind key-check sees thatseo
already exists and bails.Ideally, if the field already exists, the new object type would be compared to see if it is compatible with the interface instead of throwing an error. (However I'm unaware of any internal methods for getting a list of implementing interfaces for a GraphQL object name).
Steps to reproduce
SeoInterface
PostObjectSeo
.seo: SeoInterface
to allContentNodes
.PostObject
to override the type of your custom field:seo: PostObjectSeo
.Additional context
WPGraphQL Version
1.22.1
WordPress Version
6.5.0
PHP Version
8.1.15
Additional environment details
Ubuntu 20.04 ( wsl2 + devilbox).
Please confirm that you have searched existing issues in the repo.
Please confirm that you have disabled ALL plugins except for WPGraphQL.
The text was updated successfully, but these errors were encountered: