-
Notifications
You must be signed in to change notification settings - Fork 23
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
Ready - Improved hydration validation #463
Conversation
lib/src/main/java/graphql/nadel/validation/NadelHydrationArgumentValidation.kt
Outdated
Show resolved
Hide resolved
lib/src/main/java/graphql/nadel/validation/NadelHydrationArgumentValidation.kt
Outdated
Show resolved
Hide resolved
lib/src/main/java/graphql/nadel/validation/NadelHydrationArgumentValidation.kt
Outdated
Show resolved
Hide resolved
lib/src/main/java/graphql/nadel/validation/NadelHydrationArgumentValidation.kt
Outdated
Show resolved
Hide resolved
lib/src/main/java/graphql/nadel/validation/NadelHydrationArgumentValidation.kt
Outdated
Show resolved
Hide resolved
lib/src/main/java/graphql/nadel/validation/NadelHydrationArgumentValidation.kt
Outdated
Show resolved
Hide resolved
…entValidation.kt Co-authored-by: Franklin Wang <[email protected]>
Co-authored-by: Franklin Wang <[email protected]>
test/src/test/kotlin/graphql/nadel/tests/CentralSchemaTesting.kt
Outdated
Show resolved
Hide resolved
null | ||
StaticArgument -> { | ||
val staticArg = remoteArgSource.staticValue | ||
if (!validationUtil.isValidLiteralValue( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a note / context:
isValidLiteralValue is a public function from this class in graphql-java
:
https://github.com/graphql-java/graphql-java/blob/dd50648b5e178f965918d0c352787bd81654c7fe/src/main/java/graphql/validation/ValidationUtil.java
This is an internal class, but I have checked over the code and confirmed it is what we want, including recursively checking inner types of objects/functions and everything.
Have also added extensive tests for static args to check this in NadelHydrationArgumentValidationTest.kt
It is an internal class in
if (actorFieldArgType.isNonNull && !hydrationSourceFieldType.isNonNull) { | ||
//need to check null compatibility | ||
val sourceType = remoteArg.remoteArgumentSource.sourceType | ||
if (sourceType != ObjectField && actorFieldArgType.isNonNull && !hydrationSourceFieldType.isNonNull) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added sourceType != ObjectField
so that it ignores null compatibility for $source
arguments as that is handled differently by nadel.
(As discussed in the live PR review)
//could have ID feed into [ID] (as a possible batch hydration case). | ||
// in this case we need to unwrap the list and check types | ||
if (isBatchHydration && (!unwrappedHydrationSourceFieldType.isList && unwrappedActorFieldArgType.isList)) { | ||
val error = getHydrationInputErrors( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note:
a recurring theme here is:
val error = getErrors()
if (error != null) { return Error(blah)}
the reason we cant just simplify this to return getErrors()
is because we are recursively unwrapping the supplied & actor arg types, but for the error, it is generally more helpful for the message to display the original type, not some inner type that we have unwrapped
@@ -142,50 +139,51 @@ internal class NadelHydrationValidation( | |||
} | |||
|
|||
private fun getArgumentErrors( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actual added logic for this file is in this function
(typeToAssign.name == Scalars.GraphQLString.name || typeToAssign.name == Scalars.GraphQLInt.name)) { | ||
return true | ||
} | ||
if (targetType.name == Scalars.GraphQLString.name && typeToAssign.name == Scalars.GraphQLID.name) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Allowing ID -> String. see comment here: https://hello.atlassian.net/wiki/spaces/PSRV/pages/2987269760/Analysis+of++Current+Hydration+Arg+Validation+Errors+in+Central+Schema?focusedCommentId=2990608894
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I agree with this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, we'll have a discussion on the page
lib/src/main/java/graphql/nadel/validation/NadelHydrationValidation.kt
Outdated
Show resolved
Hide resolved
lib/src/main/java/graphql/nadel/validation/NadelHydrationArgumentValidation.kt
Outdated
Show resolved
Hide resolved
(typeToAssign.name == Scalars.GraphQLString.name || typeToAssign.name == Scalars.GraphQLInt.name)) { | ||
return true | ||
} | ||
if (targetType.name == Scalars.GraphQLString.name && typeToAssign.name == Scalars.GraphQLID.name) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I agree with this.
|
||
// scalar feed into scalar | ||
if (unwrappedHydrationSourceFieldType is GraphQLScalarType && unwrappedActorFieldArgType is GraphQLScalarType) { | ||
return validateScalarArg(hydrationSourceFieldType, actorFieldArgType, parent, overallField, remoteArg, actorFieldName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as before, can you pass in unwrappedHydrationSourceFieldType
here instead of passing in the raw GraphQLType
and then unwrapping it inside the function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
passing in wrapped type because we want to preserve the wrapped type to print in the error message to avoid any confusion from the user
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the only reason we could pass in the unwrapped type previously (in the case that its an object) is because we do not show the type in that one error message
lib/src/main/java/graphql/nadel/validation/NadelHydrationArgumentValidation.kt
Outdated
Show resolved
Hide resolved
lib/src/main/java/graphql/nadel/validation/NadelHydrationArgumentValidation.kt
Outdated
Show resolved
Hide resolved
lib/src/main/java/graphql/nadel/validation/NadelHydrationArgumentValidation.kt
Outdated
Show resolved
Hide resolved
lib/src/main/java/graphql/nadel/validation/NadelHydrationArgumentValidation.kt
Outdated
Show resolved
Hide resolved
lib/src/main/java/graphql/nadel/validation/NadelHydrationArgumentValidation.kt
Outdated
Show resolved
Hide resolved
Co-authored-by: Franklin Wang <[email protected]>
…ation.kt Co-authored-by: Franklin Wang <[email protected]>
…ssian-labs/nadel into improved-hydration-validation
Merged: https://github.com/atlassian-labs/nadel/pull/461/files/e3ff70e3eb4a60f03f1fed2a6e014dc2775de069
This PR is Ready For Review and not awaiting any other PRs 👍
Tested in central schema ✅
Passed Engine Tests ✅
Added unit tests covering all cases ✅