Skip to content

New validation rules about type, field, argument#1955

Merged
bbakerman merged 4 commits into
graphql-java:masterfrom
dugenkui03:addSchemaValidationRules
Nov 10, 2020
Merged

New validation rules about type, field, argument#1955
bbakerman merged 4 commits into
graphql-java:masterfrom
dugenkui03:addSchemaValidationRules

Conversation

@dugenkui03

@dugenkui03 dugenkui03 commented Jun 13, 2020

Copy link
Copy Markdown
Contributor

The validation about GraphQLObjectType, GraphQLInterfaceType, GraphQLUnionType, GraphQLEnumType, GraphQLInputObjectType, GraphQLScalarType.

  • Types must define one or more fields;
  • Enum type must define one or more enum values;
  • Union type must include one or more unique member types;
  • The member types of a Union type must all be Object base types;
  • Non‐Null type must not wrap another Non‐Null type;
  • Invalid name begin with "__" (two underscores).

Details in specification: TypeSystem

@dugenkui03 dugenkui03 force-pushed the addSchemaValidationRules branch from 256cb9a to a90e4e3 Compare June 13, 2020 06:55
@dugenkui03 dugenkui03 marked this pull request as ready for review June 13, 2020 07:02
@dugenkui03 dugenkui03 changed the title add new schema validation rules New schema validation rules Jun 13, 2020
@dugenkui03 dugenkui03 changed the title New schema validation rules New validation rules about type, field, argument Jun 13, 2020

@andimarek andimarek left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks a lot for these new rules.

Please have a look at my comments.


private boolean isScalarOrIntrospectionTypes(GraphQLNamedType type) {
if (type instanceof GraphQLScalarType && (
type.getName().equals("Int") || type.getName().equals("Float") || type.getName().equals("String") ||

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we should only treat the build-in scalar types (Int, Float, String, Boolean and ID) in a special way. The others are not really special and should be treated as every other custom scalar.

We also have a helper method in Scalars (I believe) to determine if the type is a build-in one or not

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for your suggestion.

return;
}

List<Type> memberTypes = definition.getMemberTypes();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we should not need to check the AST definition here. Just getting the members of the type should be enough.

@dugenkui03 dugenkui03 Jun 19, 2020

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

types in GraphQLUnionType.Builder is a Map(code link), which will lost the type with duplicated name.

Maybe it will be better to move unique member check to SchemaTypeChecker.

@dugenkui03 dugenkui03 Jun 19, 2020

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I will followed your suggestion instead of removed it, because types definied in GraphQLUnionType is list after all.

Then I will add unique member check to SchemaTypeChecker in another PR.

Is that appropriate?

}
}

private void validateObject(GraphQLObjectType type, SchemaValidationErrorCollector errorCollector) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

can we combine validateObject and validateInterface?
I would also suggest a more prescriptive name like validateContainsField or so.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for your suggestion.

return true;
}

if (type instanceof GraphQLObjectType && (

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

IntrospectionQuery is not a special type at all (it is just a name).

@dugenkui03 dugenkui03 Jun 19, 2020

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

graphql-java framework contains a type named IntrospectionQuery, which contains fields start with '__', and is used for introspection.

I add a method named isIntrospectionTypes(), which is used in filterBuiltInTypes(). details in new commit.

return graphQLNamedTypes.stream().filter(type -> !isScalarOrIntrospectionTypes(type)).collect(Collectors.toList());
}

private boolean isScalarOrIntrospectionTypes(GraphQLNamedType type) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

could this whole method just check for __ prefix?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Replace it by filterBuiltInTypes, which aimed to filter Built-In Types.

return Collections.emptyList();
}

return graphQLNamedTypes.stream().filter(type -> !isScalarOrIntrospectionTypes(type)).collect(Collectors.toList());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We have static util methods (in FpKit I believe), please use them instead of using directly filter etc.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for your suggestion.

class TypeAndFieldRuleTest extends Specification {


def "type must define one or more fields."() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we should add tests for Interfaces here as well.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for your suggestion.

errorCollector.addError(validationError);
}

List<String> typeNames = new ArrayList<>();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think a Set is better here as track just the names we already saw.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for your suggestion.

@dugenkui03 dugenkui03 requested a review from andimarek June 19, 2020 19:17
@dugenkui03 dugenkui03 force-pushed the addSchemaValidationRules branch from a23d7e4 to 59a1377 Compare June 20, 2020 11:54
@dugenkui03 dugenkui03 force-pushed the addSchemaValidationRules branch from 59a1377 to 9ff53d2 Compare June 21, 2020 04:28
@dugenkui03

Copy link
Copy Markdown
Contributor Author

hi @andimarek , appreciate your time for this. is there any thing else I need to do for this PR?

I think is is pretty important to improve schema validation in future release version.

@tfij

tfij commented Oct 21, 2020

Copy link
Copy Markdown

Hi, is there any way to help in review of this PR?
Correct schema validation is very much expected by my.

@bbakerman bbakerman added this to the 16.0 milestone Nov 10, 2020
@bbakerman bbakerman merged commit c801fd8 into graphql-java:master Nov 10, 2020
sachindshinde added a commit to apollographql/federation-jvm that referenced this pull request Jan 19, 2021
anttip added a commit to Nosto/graphql-java-annotations that referenced this pull request May 19, 2021
* Fixed test to include a field because validation in graphql now requires ypes to have one or more fields ( graphql-java/graphql-java#1955 )
* Removed references to arguments when recreation ExecutionStrategyParameters because arguments field was dropped in graphql-java ( https://github.com/graphql-java/graphql-java/pull/2023/files#diff-d31b54bc13a6051c43027e76627c6e99de28f64adfcfcfb275856ec00890cc4fL44 )
* Updated tests to work with immutable structures that graphql-java has moved to ( https://github.com/graphql-java/graphql-java/pull/2086/files#diff-9fed7fa709720e6a47a80119bb991def6fa752f8933d9f5e3dfcede5520c07d6R134 )
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.

4 participants