Skip to content
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

Assert matching response shapes in fields_will_merge #4347

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

rmosolgo
Copy link
Owner

@rmosolgo rmosolgo commented Feb 16, 2023

Oops, it seems like one part of FieldsWillMerge was missing. Adding it now might break some queries that used to work, so I may have to ensure there's a way to opt out of this change.

From the spec:

SameResponseShape(fieldA, fieldB)

  • Let typeA be the return type of fieldA.
  • Let typeB be the return type of fieldB.
  • If typeA or typeB is Non-Null:
    • If typeA or typeB is nullable, return false.
    • Let typeA be the nullable type of typeA.
    • Let typeB be the nullable type of typeB.
  • If typeA or typeB is List:
    • If typeA or typeB is not List, return false.
    • Let typeA be the item type of typeA.
    • Let typeB be the item type of typeB.
    • Repeat from step 3.
  • If typeA or typeB is Scalar or Enum:
    • If typeA and typeB are the same type return true, otherwise return false.

https://spec.graphql.org/draft/#SameResponseShape()

In GraphQL-JS:

https://github.com/graphql/graphql-js/blob/f201681bf806a2c46c4ee8b2533287421327a302/src/validation/rules/OverlappingFieldsCanBeMergedRule.ts#L691-L718

https://github.com/graphql/graphql-js/blob/a24a9f35b876bdd0d5050eca34d3020bd0db9a29/src/validation/__tests__/OverlappingFieldsCanBeMergedRule-test.ts#L738-L767

TODO:

  • Does this make other tests fail?
    • One now-removed test was added here: Interpreter type at path fix #2004 I think it was a test for code that doesn't exist anymore but ... will it cause a bug to make that fail?
  • Is this too big of a change to make at this point?
  • What about people who depend on this check not being here?
  • Performance implications?

else
true
end
elsif type2.list?
Copy link
Contributor

@gmac gmac Feb 16, 2023

Choose a reason for hiding this comment

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

Comparing this with the graphql-js implementation... Shouldn't this return true?

  if (isListType(type2)) {
    return true;
  }

end
elsif type2.non_null?
true
elsif !type1.kind.fields? && !type2.kind.fields?
Copy link
Contributor

@gmac gmac Feb 16, 2023

Choose a reason for hiding this comment

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

Again comparing this with graphql-js, I believe this should be an OR...

  if (isLeafType(type1) || isLeafType(type2)) {
    return type1 !== type2;
  }

So !type1.kind.fields? should be equivalent to isLeafType(type1), at which time the compound condition shouldn't need to change.

Copy link
Contributor

Choose a reason for hiding this comment

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

Revisiting this again today, I've noticed another issue with the fields? check in general... Right now, Union does not belong to fields which makes the fields? check a rather ambiguous slice across both Leaf and Composite distinctions. Technically Union should probably belong to fields?, although I imagine that change could have a huge blast radius across community implementations.

My suggestion then would be to introduce a proper leaf? distinction (ie: scalar? || enum?), and then refactor the core library to revolve around formal leaf? and composite? distinctions, and allow fields? to fade away into the sunset (while remaining present to support existing community usage).

Copy link
Contributor

Choose a reason for hiding this comment

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

@gmac
Copy link
Contributor

gmac commented Feb 16, 2023

Adding it now might break some queries that used to work, so I may have to ensure there's a way to opt out of this change.

Unfortunately, yes... this is a breaking change that will start rejecting queries that used to be accepted. Probably the smoothest path to reaching spec would be to make this an opt-in setting on GraphQL::Schema that is off by default for now and activates in the next major release.

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