Skip to content

Commit 0debef3

Browse files
committed
Put validate behinda flag on the SchemaBuilder
1 parent 5ea1d0e commit 0debef3

File tree

4 files changed

+54
-24
lines changed

4 files changed

+54
-24
lines changed

graphql-builder/src/main/java/com/phocassoftware/graphql/builder/EntityProcessor.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import graphql.schema.GraphQLOutputType;
2222
import graphql.schema.GraphQLScalarType;
2323
import graphql.schema.GraphQLType;
24+
2425
import java.lang.annotation.Annotation;
2526
import java.lang.reflect.AnnotatedElement;
2627
import java.lang.reflect.Type;
@@ -38,13 +39,13 @@ public class EntityProcessor {
3839
private final Map<String, EntityHolder> entities;
3940
private final MethodProcessor methodProcessor;
4041

41-
EntityProcessor(DataFetcherRunner dataFetcherRunner, List<GraphQLScalarType> scalars, DirectivesSchema diretives) {
42-
this.methodProcessor = new MethodProcessor(dataFetcherRunner, this, diretives);
42+
EntityProcessor(DataFetcherRunner dataFetcherRunner, List<GraphQLScalarType> scalars, DirectivesSchema directives) {
43+
this.methodProcessor = new MethodProcessor(dataFetcherRunner, this, directives);
4344
this.entities = new HashMap<>();
4445
addDefaults();
4546
addScalars(scalars);
4647

47-
this.directives = diretives;
48+
this.directives = directives;
4849
}
4950

5051
private void addDefaults() {

graphql-builder/src/main/java/com/phocassoftware/graphql/builder/MethodProcessor.java

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public MethodProcessor(DataFetcherRunner dataFetcherRunner, EntityProcessor enti
6666
graphSubscriptions.name("Subscriptions");
6767
}
6868

69-
void process(AuthorizerSchema authorizer, Method method) {
69+
void process(AuthorizerSchema authorizer, Method method, boolean shouldValidate) {
7070
if (!Modifier.isStatic(method.getModifiers())) {
7171
throw new RuntimeException("End point must be a static method");
7272
}
@@ -85,10 +85,14 @@ void process(AuthorizerSchema authorizer, Method method) {
8585
return;
8686
}
8787

88-
object.field(process(authorizer, coordinates, null, method));
88+
object.field(process(authorizer, coordinates, null, method, shouldValidate));
8989
}
9090

9191
Builder process(AuthorizerSchema authorizer, FieldCoordinates coordinates, TypeMeta parentMeta, Method method) {
92+
return process(authorizer, coordinates, parentMeta, method, false);
93+
}
94+
95+
Builder process(AuthorizerSchema authorizer, FieldCoordinates coordinates, TypeMeta parentMeta, Method method, boolean shouldValidate) {
9296
GraphQLFieldDefinition.Builder field = GraphQLFieldDefinition.newFieldDefinition();
9397

9498
entityProcessor.addSchemaDirective(method, method.getDeclaringClass(), field::withAppliedDirective);
@@ -130,22 +134,28 @@ Builder process(AuthorizerSchema authorizer, FieldCoordinates coordinates, TypeM
130134
field.argument(argument);
131135
}
132136

133-
DataFetcher<?> fetcher = buildFetcher(directives, authorizer, method, meta);
137+
DataFetcher<?> fetcher = buildFetcher(directives, authorizer, method, meta, shouldValidate);
134138
codeRegistry.dataFetcher(coordinates, fetcher);
135139
return field;
136140
}
137141

138-
private <T extends Annotation> DataFetcher<?> buildFetcher(DirectivesSchema diretives, AuthorizerSchema authorizer, Method method, TypeMeta meta) {
139-
DataFetcher<?> fetcher = buildDataFetcher(meta, method);
140-
fetcher = diretives.wrap(method, meta, fetcher);
142+
private <T extends Annotation> DataFetcher<?> buildFetcher(
143+
DirectivesSchema directives,
144+
AuthorizerSchema authorizer,
145+
Method method,
146+
TypeMeta meta,
147+
boolean shouldValidate
148+
) {
149+
DataFetcher<?> fetcher = buildDataFetcher(meta, method, shouldValidate);
150+
fetcher = directives.wrap(method, meta, fetcher);
141151

142152
if (authorizer != null) {
143153
fetcher = authorizer.wrap(fetcher, method);
144154
}
145155
return fetcher;
146156
}
147157

148-
private DataFetcher<?> buildDataFetcher(TypeMeta meta, Method method) {
158+
private DataFetcher<?> buildDataFetcher(TypeMeta meta, Method method, boolean shouldValidate) {
149159
Function<DataFetchingEnvironment, Object>[] resolvers = new Function[method.getParameterCount()];
150160

151161
method.setAccessible(true);
@@ -163,9 +173,11 @@ private DataFetcher<?> buildDataFetcher(TypeMeta meta, Method method) {
163173

164174
DataFetcher<?> fetcher = env -> {
165175
try {
166-
List<GraphQLError> errors = validationRules.runValidationRules(env);
167-
if (!errors.isEmpty()) {
168-
return DataFetcherResult.newResult().errors(errors).data(null).build();
176+
if (shouldValidate) {
177+
List<GraphQLError> errors = validationRules.runValidationRules(env);
178+
if (!errors.isEmpty()) {
179+
return DataFetcherResult.newResult().errors(errors).data(null).build();
180+
}
169181
}
170182

171183
Object[] args = new Object[resolvers.length];

graphql-builder/src/main/java/com/phocassoftware/graphql/builder/SchemaBuilder.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,10 @@ private SchemaBuilder processTypes(Set<Class<?>> types) {
5757
return this;
5858
}
5959

60-
private SchemaBuilder process(HashSet<Method> endPoints) throws ReflectiveOperationException {
60+
private SchemaBuilder process(HashSet<Method> endPoints, boolean shouldValidate) throws ReflectiveOperationException {
6161
var methodProcessor = this.entityProcessor.getMethodProcessor();
6262
for (var method : endPoints) {
63-
methodProcessor.process(authorizer, method);
63+
methodProcessor.process(authorizer, method, shouldValidate);
6464
}
6565

6666
return this;
@@ -112,6 +112,7 @@ public static class Builder {
112112
private DataFetcherRunner dataFetcherRunner = (method, fetcher) -> fetcher;
113113
private final List<String> classpaths = new ArrayList<>();
114114
private final List<GraphQLScalarType> scalars = new ArrayList<>();
115+
private boolean shouldValidate = false;
115116

116117
private Builder() {}
117118

@@ -130,6 +131,11 @@ public Builder scalar(GraphQLScalarType scalar) {
130131
return this;
131132
}
132133

134+
public Builder validate() {
135+
this.shouldValidate = true;
136+
return this;
137+
}
138+
133139
public GraphQLSchema.Builder build() {
134140
try {
135141
this.scalar(ExtendedScalars.GraphQLLong);
@@ -158,7 +164,7 @@ public GraphQLSchema.Builder build() {
158164

159165
return new SchemaBuilder(dataFetcherRunner, scalars, directivesSchema, authorizer)
160166
.processTypes(types)
161-
.process(endPoints)
167+
.process(endPoints, shouldValidate)
162168
.build(schemaConfiguration);
163169
} catch (ReflectiveOperationException e) {
164170
throw new RuntimeException(e);

graphql-builder/src/test/java/com/phocassoftware/graphql/builder/JakartaValidationDirectiveTest.java

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ void testJakartaSizeAnnotationAddedAsDirectiveOnARecord() {
3838

3939
@Test
4040
void testJakartaSizeDirectiveArgumentDefinition() {
41-
Map<String, Object> response = execute("query IntrospectionQuery { __schema { directives { name locations args { name } } } }", null).getData();
41+
Map<String, Object> response = execute("query IntrospectionQuery { __schema { directives { name locations args { name } } } }", null, true).getData();
4242
List<LinkedHashMap<String, Object>> dir = (List<LinkedHashMap<String, Object>>) ((Map<String, Object>) response.get("__schema")).get("directives");
4343
LinkedHashMap<String, Object> constraint = dir.stream().filter(map -> map.get("name").equals("Size")).collect(Collectors.toList()).get(0);
4444

@@ -56,38 +56,49 @@ void testJakartaSizeDirectiveArgumentDefinition() {
5656
@Test
5757
void testJakartaSizeValidationIsApplied() {
5858
var name = "Roger";
59-
Map<String, String> response = execute("mutation setName($name: String!){setName(name: $name)} ", Map.of("name", name)).getData();
59+
Map<String, String> response = execute("mutation setName($name: String!){setName(name: $name)} ", Map.of("name", name), true).getData();
6060
var result = response.get("setName");
6161

6262
assertEquals(name, result);
6363

6464
name = "Po";
65-
var error = execute("mutation setName($name: String!){setName(name: $name)} ", Map.of("name", name)).getErrors().getFirst();
65+
var error = execute("mutation setName($name: String!){setName(name: $name)} ", Map.of("name", name), true).getErrors().getFirst();
6666

6767
assertEquals("size must be between 3 and 2147483647", error.getMessage());
6868
}
6969

70+
@Test
71+
void testJakartaSizeValidationIsNotAppliedWhenFlagIsFalse() {
72+
var name = "Po";
73+
Map<String, String> response = execute("mutation setName($name: String!){setName(name: $name)} ", Map.of("name", name), false).getData();
74+
var result = response.get("setName");
75+
76+
assertEquals(name, result);
77+
}
78+
7079
@Test
7180
void testJakartaMinAndMaxValidationIsApplied() {
7281
var age = 4;
73-
Map<String, Integer> response = execute("mutation setAge($age: Int!){setAge(age: $age)} ", Map.of("age", age)).getData();
82+
Map<String, Integer> response = execute("mutation setAge($age: Int!){setAge(age: $age)} ", Map.of("age", age), true).getData();
7483
var result = response.get("setAge");
7584

7685
assertEquals(age, result);
7786

7887
age = 2;
79-
var error = execute("mutation setAge($age: Int!){setAge(age: $age)} ", Map.of("age", age)).getErrors().getFirst();
88+
var error = execute("mutation setAge($age: Int!){setAge(age: $age)} ", Map.of("age", age), true).getErrors().getFirst();
8089

8190
assertEquals("must be greater than or equal to 3", error.getMessage());
8291

8392
age = 100;
84-
error = execute("mutation setAge($age: Int!){setAge(age: $age)} ", Map.of("age", age)).getErrors().getFirst();
93+
error = execute("mutation setAge($age: Int!){setAge(age: $age)} ", Map.of("age", age), true).getErrors().getFirst();
8594

8695
assertEquals("must be less than or equal to 99", error.getMessage());
8796
}
8897

89-
private ExecutionResult execute(String query, Map<String, Object> variables) {
90-
GraphQLSchema preSchema = SchemaBuilder.builder().classpath("com.phocassoftware.graphql.builder.type.directive").build().build();
98+
private ExecutionResult execute(String query, Map<String, Object> variables, boolean validate) {
99+
var builder = SchemaBuilder.builder().classpath("com.phocassoftware.graphql.builder.type.directive");
100+
if (validate) builder = builder.validate();
101+
GraphQLSchema preSchema = builder.build().build();
91102
GraphQL schema = GraphQL.newGraphQL(new IntrospectionWithDirectivesSupport().apply(preSchema)).build();
92103

93104
var input = ExecutionInput.newExecutionInput();

0 commit comments

Comments
 (0)