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

Implement OneOf Input Objects via @oneOf directive #3513

Merged
merged 19 commits into from
Jun 27, 2023

Conversation

erikkessler1
Copy link
Contributor

@erikkessler1 erikkessler1 commented Mar 18, 2022

This PR implements graphql/graphql-spec#825 to add a @oneOf directive that indicates an Object is a OneOf Object or an Input Object is a OneOf Input Object. We then validate OneOf Objects and OneOf Input Objects conform to the spec during the validation and execution phases.

Closes graphql/graphql-wg#648

This adds the @OneOf directive as a default directive to indicate
Objects and Input Objects as OneOf Objects/Input Objects which ensure
there is exactly one non-null entry. Future commits will work to
implement this directive.
This exposes a new boolean `oneOf` field on `__Type` that indicates if
a type is `oneOf`. We implement by checking if the AST node for the
object contains a `@oneOf` directive.
This validates that all fields of oneOf objects are nullable and that
all fields of oneOf input object are nullable and do not have a
default value.
This ensures that OneOf Input Objects have exactly one field provided
with the correct non-null, type for that field. Additionally, a
variable used in a OneOf Input Object must be non-nullable.
This ensures that we enforce the rules for OneOf Input Objects at
execution time.
This ensures the OneOf Objects resolve to an object with exactly one
non-null entry.
@linux-foundation-easycla
Copy link

linux-foundation-easycla bot commented Mar 18, 2022

CLA Signed

The committers listed above are authorized under a signed CLA.

@netlify
Copy link

netlify bot commented Mar 18, 2022

Deploy Preview for compassionate-pike-271cb3 failed.

Name Link
🔨 Latest commit cfc68cd
🔍 Latest deploy log https://app.netlify.com/sites/compassionate-pike-271cb3/deploys/64677c014a3b3100086e8c6d

Copy link
Member

@benjie benjie left a comment

Choose a reason for hiding this comment

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

Thank you for putting the time into writing this, and sorry it has taken me so long to get around to reviewing it.

From reviewing the work you've done, it's clear that I need to put some significant time into specifying oneOf objects, at the moment the implementations in here don't align with what I'm imagining, and they're inconsistent with how input objects are specified. Given the questions your work raises, I think the best approach is for me to figure out the answers before any more work is done towards supporting oneOf objects.

As for oneOf input objects, this is all the spec PR addresses currently; would it make sense to cut down this PR to only deal with oneOf input objects to get this closer to review?

src/execution/__tests__/oneof-test.ts Outdated Show resolved Hide resolved
src/execution/__tests__/oneof-test.ts Show resolved Hide resolved
src/execution/__tests__/oneof-test.ts Show resolved Hide resolved
src/execution/__tests__/oneof-test.ts Show resolved Hide resolved
src/execution/__tests__/oneof-test.ts Outdated Show resolved Hide resolved
src/execution/__tests__/oneof-test.ts Outdated Show resolved Hide resolved
src/execution/__tests__/oneof-test.ts Outdated Show resolved Hide resolved
src/execution/__tests__/oneof-test.ts Outdated Show resolved Hide resolved
We need to more fully specify how oneOf objects should behave, so we
are removing them for now.
@erikkessler1
Copy link
Contributor Author

As for oneOf input objects, this is all the spec PR addresses currently; would it make sense to cut down this PR to only deal with oneOf input objects to get this closer to review?

Thank you for taking a look! I agree that focusing on oneOf input objects makes sense, so I've stripped out everything around oneOf objects.

@erikkessler1 erikkessler1 changed the title Implement OneOf Input Objects and OneOf Objects via @oneOf directive Implement OneOf Input Objects via @oneOf directive Apr 2, 2022
@benjie
Copy link
Member

benjie commented Apr 4, 2022

Odd, all my comments seem to have been duplicated; I've deleted the duplicates.

Copy link
Member

@benjie benjie left a comment

Choose a reason for hiding this comment

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

This is looking good 👍

My main concern right now is very JS-specific, and it's that we've not tested undefined and I think that might cause a whole host of issues with the Object.keys strategy. Though GraphQL typically uses JSON (which drops undefined) this is not always the case; I'm concerned that variables: { a: "abc", b: undefined } which should be valid might not be seen as such. Please add some tests for this so we can check 🙏

src/execution/__tests__/oneof-test.ts Show resolved Hide resolved
src/type/__tests__/introspection-test.ts Show resolved Hide resolved
src/utilities/__tests__/valueFromAST-test.ts Show resolved Hide resolved
src/utilities/coerceInputValue.ts Show resolved Hide resolved
@graphql graphql deleted a comment from github-actions bot Apr 4, 2022
@graphql graphql deleted a comment from github-actions bot Apr 4, 2022
@erikkessler1
Copy link
Contributor Author

I've added some test coverage for those cases including the variables: { a: "abc", b: undefined } case.

Copy link
Member

@benjie benjie left a comment

Choose a reason for hiding this comment

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

Looks good to me - excellent work @erikkessler1! Will need a proper review from someone more familiar with GraphQL.js than I, but it feels like this implements the behaviour in the oneof spec accurately.

GraphQL.js reviewer: please pay special attention to the error messages, I'm not sure of the conventions here. Feel free to ping me (here or via DM) to discuss if needed.

@benjie
Copy link
Member

benjie commented May 23, 2022

Pushed a commit that hopefully deals with the code coverage issue 👍

@benjie
Copy link
Member

benjie commented May 23, 2022

Merged main; CI passing now 🙌

src/type/introspection.ts Outdated Show resolved Hide resolved
src/type/introspection.ts Show resolved Hide resolved
@benjie
Copy link
Member

benjie commented May 25, 2022

Great feedback, thanks @IvanGoncharov!

@benjie
Copy link
Member

benjie commented Feb 22, 2023

@graphql/graphql-js-reviewers I've merged in the latest main, so it should be good for review 👍

@IvanGoncharov Can you dismiss your stale review, please?

@saltman424
Copy link

@IvanGoncharov any chance you can dismiss the review @benjie mentioned above? I know this has been a long awaited feature for many

@yalshekerchi
Copy link

@IvanGoncharov It looks like the changes requested from your review have been addressed. Just kindly wanted to remind you about this as the review is stale at this point.

@benjie Do you anticipate any further changes expected to be made on this PR? I was just curious about the status of this feature and what else needs to be done.

@benjie
Copy link
Member

benjie commented May 11, 2023

I'm not aware of any expected changes.

Copy link
Member

@IvanGoncharov IvanGoncharov left a comment

Choose a reason for hiding this comment

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

It's a partial review. I will find time for other files soon.

Also, please update these files to have the new type with @oneOf: https://github.com/graphql/graphql-js/blob/e17a0897f67305626c6090ce0174f101b7a96fc4/src/__testUtils__/kitchenSinkSDL.ts

src/execution/__tests__/oneof-test.ts Outdated Show resolved Hide resolved
src/execution/__tests__/oneof-test.ts Show resolved Hide resolved
src/execution/__tests__/oneof-test.ts Show resolved Hide resolved
src/execution/__tests__/oneof-test.ts Outdated Show resolved Hide resolved
src/execution/__tests__/oneof-test.ts Show resolved Hide resolved
src/execution/__tests__/oneof-test.ts Show resolved Hide resolved
src/execution/__tests__/oneof-test.ts Show resolved Hide resolved
src/type/__tests__/introspection-test.ts Outdated Show resolved Hide resolved
src/type/__tests__/introspection-test.ts Outdated Show resolved Hide resolved
src/type/__tests__/introspection-test.ts Outdated Show resolved Hide resolved
@IvanGoncharov IvanGoncharov added spec RFC Implementation of a proposed change to the GraphQL specification PR: feature 🚀 requires increase of "minor" version number labels May 18, 2023
@IvanGoncharov
Copy link
Member

Sorry missed that spec proposal in stage 2, so this PR can actually be merged.
Also missed all the comments (my inbox is in bad shape atm).
@benjie Thank you for the ping 👍

@erikkessler1 If you don't mind, I will address stylistic changes by just committing on top of your PR.
I think it would be faster that way, it takes a lot of time to comment on a lot of tiny changes.

@erikkessler1
Copy link
Contributor Author

If you don't mind, I will address stylistic changes by just committing on top of your PR.
I think it would be faster that way, it takes a lot of time to comment on a lot of tiny changes.

@IvanGoncharov that sounds good to me!

@IvanGoncharov
Copy link
Member

@erikkessler1 Thanks for addressing my review comments, and sorry for the delay 🙇
I'm still planning to review/merge this PR, and I will try to find time this weekend.

@IvanGoncharov
Copy link
Member

@erikkessler1 Sorry, I didn't find time for a quality review.
That said, the last time I reviewed it, all issues were non-critical and could be fixed later.
Since there were no other objections I will merge it as is.

@IvanGoncharov IvanGoncharov merged commit 8cfa3de into graphql:main Jun 27, 2023
@erikkessler1 erikkessler1 deleted the oneof-implementation-objects branch June 27, 2023 12:16
spawnia added a commit to spawnia/graphql-js that referenced this pull request Jul 17, 2023
Follow up from graphql#3513.

I think it is fine for the spec text in graphql/graphql-spec#825
to refer to `OneOf Input Object`, as the spec explains
what that is in another section. In a directive definition, that explanation by itself
does not make much sense without prior knowledge.
@yaacovCR yaacovCR mentioned this pull request Mar 22, 2024
benjie pushed a commit that referenced this pull request Jun 21, 2024
Co-authored-by: Benjie Gillam <benjie@jemjie.com>
Closes graphql/graphql-wg#648
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PR: feature 🚀 requires increase of "minor" version number spec RFC Implementation of a proposed change to the GraphQL specification
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[2021-03-04] Implement Oneof Input Objects in GraphQL.js
6 participants