spring-projects / spring-graphql

Spring Integration for GraphQL
https://spring.io/projects/spring-graphql
Apache License 2.0
1.52k stars 297 forks source link

integration spring validation #125

Closed Diluka closed 3 years ago

Diluka commented 3 years ago

bring validation annotations to graphql directives

hantsy commented 3 years ago

The existing graphql-java-extended-validation is based on Bean Validation specification, it is easy to add it to Spring GraphQL via RuntimeWiringConfigurer.

ValidationRules validationRules = ValidationRules.newValidationRules()
                .onValidationErrorStrategy(OnValidationErrorStrategy.RETURN_NULL)
                .build();
//
// This will rewrite your data fetchers when rules apply to them so that validation
ValidationSchemaWiring schemaWiring = new ValidationSchemaWiring(validationRules);
//
// we add this schema wiring to the graphql runtime
builder.directiveWiring(schemaWiring);
Diluka commented 3 years ago

The existing graphql-java-extended-validation is based on Bean Validation specification, it is easy to add it to Spring GraphQL via RuntimeWiringConfigurer.

ValidationRules validationRules = ValidationRules.newValidationRules()
                .onValidationErrorStrategy(OnValidationErrorStrategy.RETURN_NULL)
                .build();
//
// This will rewrite your data fetchers when rules apply to them so that validation
ValidationSchemaWiring schemaWiring = new ValidationSchemaWiring(validationRules);
//
// we add this schema wiring to the graphql runtime
builder.directiveWiring(schemaWiring);

does it work now? i tried last week, crashed https://github.com/graphql-java/graphql-java-extended-validation/issues/51

hantsy commented 3 years ago

@Diluka yeah, I tried it in the my Dgs example, there is a conflict between the hibernate validators and graphql java verison, Dgs still used 16.x, so I used an older version of Hibernate Validator.

Check the configuration here: https://github.com/hantsy/spring-graphql-sample/blob/master/dgs-codegen/src/main/java/com/example/demo/gql/CustomRuntimeWiring.java

And declaring a Size in the GraphQL schema file, https://github.com/hantsy/spring-graphql-sample/blob/master/dgs-codegen/src/main/resources/schema/schema.graphql#L5

It works as expected.

Diluka commented 3 years ago

@hantsy I have tried. using 16.x will break querydsl integration.

hantsy commented 3 years ago

The example I mentioned above used Netflix Dgs framework which still used GraphQL Java 16.x, not Spring GraphQL.

bclozel commented 3 years ago

Considered under #110

rstoyanchev commented 3 years ago

@Diluka just curious if you were interested specifically in Bean Validation expressed as annotations in schema directives, as opposed to something like #110 where Bean Validation is expressed as annotations on Java objects and applied when those are used as @Argument handler method arguments?

bclozel commented 3 years ago

@rstoyanchev Should we broaden the scope of #110 or reopen this one? Someone already made the point of directives in #110.

Diluka commented 3 years ago

@rstoyanchev

for most crud like apis, I don't want to create a lot of java dto classes, when graphql can be verified. and repo save method take only entity object not dto. it is not so flexible as it plays in javascript.

and querydsl generated apis have no dto classes to use Bean Validation.

and maybe mock schema alone

rstoyanchev commented 3 years ago

@Diluka, the Bean Validation annotations can be placed on entity objects. Why separate DTO objects?

Diluka commented 3 years ago

@rstoyanchev DTO is not equal to Entity

there are very like but not the same.

for example, two apis have like but different DTO and validation, and process to the same Entity Class object to db. In graphql we use input types and validation directives to filter properties and validate them. and use the same Entity Class in controller method args to receive them and do additional process and save into db. So if the properties are compatible we don't need create additional DTO class and transform them into Entity for saving. And due to the differences we can't use annotations on Entity class.