Description
What problem does this address?
When trying to do things like add Where Args to all connections to a specific type it's cumbersome to do so.
With Object Types, we can add a field to ContentNode
and all Types that implement the interface get the field.
But with Input Types there's no concept of Input Interfaces, so each unique connection cannot inherit a general set of fields like Object Types can.
If we wanted to add a custom where arg to all "post" connections, it becomes tricky.
If using register_graphql_field()
I would have to know the names of all possible Post
connections and do something like:
register_graphql_field( 'RootQueryToPostConnectionWhereArgs', 'myCustomInputField', [] );
register_graphql_field( 'UserToPostConnectionWhereArgs', 'myCustomInputField', [] );
register_graphql_field( 'TagToPostConnectionWhereArgs', 'myCustomInputField', [] );
register_graphql_field( 'CategoryToPostConnectionWhereArgs', 'myCustomInputField', [] );
...
...and so on
This doesn't scale!
I can't / don't want to attempt to keep up with all the possible types I would need to filter. When it comes to things like ACF that add even more Types to the Schema, etc it is essentially impossible to know all the connections that may exist in the schema.
To get around this, we could add a filter like so:
add_filter( 'graphql_input_fields', function( $fields, $type_name, $config, $type_registry ) {
$post_connection = 'ToPostConnectionWhereArgs';
// If the Input Type is NOT where args on a connection "To Post", don't apply any changes
if ( substr( $type_name, -strlen( $post_connection ) ) !== $post_connection ) {
return $fields;
}
$fields['offsetPagination'] = [
'type' => 'OffsetPagination',
'description' => __( 'Paginate content nodes with offsets', 'your-textdomain' ),
];
return $fields;
}, 10, 4 );
This should work and is certainly better than register_graphql_field()
for unknown to add a where arg to all Post connections, but feels clunky. . .and I'd still have to map how the input argument impacts the underlying resolution.
Another (cleaner) option would be hooking into the connection Instantiation like so:
add_action( 'graphql_wp_connection_type', function( array $connection_config, \WPGraphQL\Type\WPConnectionType $wp_connection_type ) {
if ( 'product' !== $connection_config['toType'] ) {
return;
}
$wp_connection_type->where_args[ 'offsetPagination' ] = [
'type' => 'OffsetPagination',
'description' => __( 'Paginate content nodes with offsets', 'your-textdomain' ),
];
} );
This is looking much better!
But I still need to map the new arg to underlying resolution.
What is your proposed solution?
I propose we introduce a register_graphql_connection_where_arg()
API that makes it easier to add an argument to connection(s) AND map the argument to the underlying execution.
Something to the tune of:
function register_graphql_connection_where_arg( $to_type, $arg_name, $arg_config ) { ... };
which could be used like so:
register_graphql_connection_where_arg( 'Product', 'offsetPagination' [
'type' => 'OffsetPagination',
'description' => __( 'Paginate content nodes with offsets', 'your-textdomain' ),
'map_input_arg' => function( $input ) { // this would be where we define how the input field maps to the underlying WP_Query (or similar) that would execute },
] );
What alternatives have you considered?
(see possible alternatives above)
Additional Context
No response
Metadata
Metadata
Assignees
Labels
Type
Projects
Status