Skip to content

feat: add directive-aware field selection - #1971

Open
simPod wants to merge 1 commit into
webonyx:masterfrom
simPod:feat/respect-field-selection-directives
Open

feat: add directive-aware field selection#1971
simPod wants to merge 1 commit into
webonyx:masterfrom
simPod:feat/respect-field-selection-directives

Conversation

@simPod

@simPod simPod commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

Context

Resolvers can use field selections to optimize data fetching, but ResolveInfo::getFieldSelection() includes selections disabled by @skip and @include. This can cause unnecessary work when clients use conditional selections.

Decision

Add the opt-in ResolveInfo::getFieldSelectionRespectingDirectives() method. It evaluates built-in selection directives with operation variables while leaving the existing method unchanged for backward compatibility.

Document the method in the resolver optimization guide and cover fields, fragment spreads, inline fragments, nested selections, directive precedence, repeated fragments, and legacy behavior.

Consequences

  • Existing callers keep their current behavior.
  • Callers can opt into a selection map that matches conditional execution.
  • Conditional type fragments remain outside the scope of field-selection analysis.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an opt-in directive-aware alternative to ResolveInfo::getFieldSelection() so resolver optimizations can ignore selections disabled by @skip / @include, while keeping legacy behavior unchanged for existing callers.

Changes:

  • Introduce ResolveInfo::getFieldSelectionRespectingDirectives() with directive evaluation against operation variables.
  • Add unit tests covering conditional fields, fragment spreads (including repeats), inline fragments, nesting, and directive precedence.
  • Update resolver optimization documentation and class reference; add a changelog entry.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/Type/Definition/ResolveInfo.php Adds directive-aware field selection folding/merging and a new public API method.
tests/Type/ResolveInfoTest.php Adds test coverage validating directive-respecting behavior vs legacy behavior.
docs/data-fetching.md Updates resolver optimization example and guidance to use the new method when directives are present.
docs/class-reference.md Documents the new ResolveInfo method in the API reference.
CHANGELOG.md Notes the new API addition under “Unreleased”.
Suppressed comments (2)

src/Type/Definition/ResolveInfo.php:512

  • This helper is protected, which makes it part of the subclass API surface. If subclasses are not intended to customize directive-aware merging, making this private (consistent with foldSelectionSet) reduces long-term compatibility constraints.
    protected function mergeSelectionsRespectingDirectives(array $left, array $right): array

src/Type/Definition/ResolveInfo.php:532

  • This method is protected, which exposes a new override point in ResolveInfo. If overriding isn't an intended extension mechanism, prefer private to keep directive-inclusion rules stable and avoid subclass behavior changes.
    protected function shouldIncludeSelectionNodeRespectingDirectives(SelectionNode $node): bool

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

*
* @return array<string, mixed>
*/
protected function foldSelectionSetRespectingDirectives(SelectionSetNode $selectionSet, int $descend): array

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keeping these helpers protected is intentional. CONTRIBUTING.md requires protected over private for extensibility (Extensibility > protected over private). The existing private helper does not override that documented rule.

}

/**
* @param FragmentSpreadNode|FieldNode|InlineFragmentNode $node

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The narrower PHPDoc is intentional. SelectionNode is an empty marker interface, while this method accepts the three concrete selection node types. This also matches the PHPDoc on ReferenceExecutor::shouldIncludeNode(), so keeping the union helps static analysis and preserves consistency.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants