wp-graphql / wp-graphql/wp-graphql

Enhance `register_graphql_connection_where_arg` to support resolver mapping and registration across all connections to a type

Open
#3,065 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

component: architecture component: connections component: input component: query effort: high impact: high needs: discussion scope: api type: enhancement
Dominant language
PHP
Stars
3.8k
Forks
472
Avg merge
1d 7h
Merged PRs (30d)
85

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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the proposed register_graphql_connection_where_arg API alongside the graphql_input_fields and graphql_wp_connection_type alternatives described in the issue. Define how a target type selects all matching connections, how the argument is registered, and how map_input_arg affects execution; done means the API supports registration and resolver mapping without listing connection names.

Written by the indexing model from the issue text.

Assessment

Tech stack
graphql, php
Domain
api, backend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.