Skip to content

fix: validate subscription with conditional selections #963

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

Merged
merged 4 commits into from
Apr 15, 2025

Conversation

dariuszkuc
Copy link
Member

Adds validation for subscription operations that specify @skip/@include conditionals on root selections.

See: graphql/graphql-spec#860

@dariuszkuc dariuszkuc requested a review from a team as a code owner April 3, 2025 23:51
Copy link
Contributor

@SimonSapin SimonSapin left a comment

Choose a reason for hiding this comment

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

Should this PR wait until graphql/graphql-spec#860 is merged?

Comment on lines 51 to 90
let has_conditional_field = fields
.iter()
Copy link
Contributor

Choose a reason for hiding this comment

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

This only considers field selections, but the spec’s For each {selection} in {selectionSet} suggests we should also check for @skip or @include on inline fragments or fragment spreads

@dariuszkuc
Copy link
Member Author

Should this PR wait until graphql/graphql-spec#860 is merged?

graphql-js PR was already merged so I'd argue that we should merge this ASAP.

});
if let Some(conditional_selection) = has_conditional_selection {
diagnostics.push(
operation.location(),
Copy link
Contributor

Choose a reason for hiding this comment

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

This is the location / source span for the entire operation all the way until }. As the snapshots below show, Ariadne renders it as:

 1 │ ╭─▶ subscription ConditionalInlineSub($condition: Boolean = true) {
   ┆ ┆   
 5 │ ├─▶ }
   │ │       
   │ ╰───────

I think it’d be more useful/precise to have the .location() of the conditional directive instead

operation.location(),
executable::BuildError::SubscriptionUsesConditionalSelection {
name: operation.name.clone(),
selection: conditional_selection.clone(),
Copy link
Contributor

Choose a reason for hiding this comment

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

Printing an entire selection set can get verbose. I think with the more precise location (previous comment) this field can be removed entirely


// first rule validates that we only have single selection
let has_conditional_selection =
operation.selection_set.selections.iter().find(|selection| {
Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry for the back-and-forth, but now this lacks spec algorithm’s recursion and fails to catch something like subscription { ... { field @skip } }. I’ll move the check into expand_selections

dariuszkuc and others added 4 commits April 9, 2025 10:33
Adds validation for subscription operations that specify `@skip`/`@include` conditionals on root selections.

See: graphql/graphql-spec#860
* Recur into inline fragments and fragment spread
* Point to the faulty directive
* Skip printing an entire selection set
@dariuszkuc dariuszkuc force-pushed the conditional_subscriptions branch from be2f362 to a11a530 Compare April 9, 2025 15:33
selection_set: &'doc executable::SelectionSet,
seen: &mut HashSet<&'doc Name>,
f: &mut dyn FnMut(&'doc executable::Selection),
) -> Result<(), RecursionLimitError> {
Copy link
Member

Choose a reason for hiding this comment

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

The implementation here doesn't actually raise a RecursionLimitError right now, but that will be part of a follow-up PR

@goto-bus-stop goto-bus-stop merged commit df16557 into main Apr 15, 2025
12 checks passed
@goto-bus-stop goto-bus-stop deleted the conditional_subscriptions branch April 15, 2025 08:58
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.

3 participants