-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Expand file tree
/
Copy pathParseAndValidate.java
More file actions
155 lines (143 loc) · 7.21 KB
/
ParseAndValidate.java
File metadata and controls
155 lines (143 loc) · 7.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package graphql;
import graphql.language.Document;
import graphql.parser.InvalidSyntaxException;
import graphql.parser.Parser;
import graphql.parser.ParserEnvironment;
import graphql.parser.ParserOptions;
import graphql.schema.GraphQLSchema;
import graphql.validation.OperationValidationRule;
import graphql.validation.QueryComplexityLimits;
import graphql.validation.ValidationError;
import graphql.validation.Validator;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
import java.util.List;
import java.util.Locale;
import java.util.function.Predicate;
import static graphql.Assert.assertNotNull;
import static java.util.Optional.ofNullable;
/**
* This class allows you to parse and validate a graphql query without executing it. It will tell you
* if it's syntactically valid and also semantically valid according to the graphql specification
* and the provided schema.
*/
@PublicApi
@NullMarked
public class ParseAndValidate {
/**
* This {@link GraphQLContext} hint can be used to supply a Predicate to the Validator so that certain rules can be skipped.
*
* This is an internal capability that you should use at your own risk. While we intend for this to be present for some time, the validation
* rule class names may change, as may this mechanism.
*/
@Internal
public static final String INTERNAL_VALIDATION_PREDICATE_HINT = "graphql.ParseAndValidate.Predicate";
/**
* This can be called to parse and validate a graphql query against a schema, which is useful if you want to know if it would be acceptable
* for execution.
*
* @param graphQLSchema the schema to validate against
* @param executionInput the execution input containing the query
*
* @return a result object that indicates how this operation went
*/
public static ParseAndValidateResult parseAndValidate(@NonNull GraphQLSchema graphQLSchema, @NonNull ExecutionInput executionInput) {
ParseAndValidateResult result = parse(executionInput);
if (!result.isFailure()) {
List<ValidationError> errors = validate(graphQLSchema, assertNotNull(result.getDocument(), "Parse result document cannot be null when parse succeeded"), executionInput.getLocale());
return result.transform(builder -> builder.validationErrors(errors));
}
return result;
}
/**
* This can be called to parse (but not validate) a graphql query.
*
* @param executionInput the input containing the query
*
* @return a result object that indicates how this operation went
*/
public static ParseAndValidateResult parse(@NonNull ExecutionInput executionInput) {
try {
//
// we allow the caller to specify new parser options by context
ParserOptions parserOptions = executionInput.getGraphQLContext().get(ParserOptions.class);
// we use the query parser options by default if they are not specified
parserOptions = ofNullable(parserOptions).orElse(ParserOptions.getDefaultOperationParserOptions());
Parser parser = new Parser();
Locale locale = executionInput.getLocale();
ParserEnvironment parserEnvironment = ParserEnvironment.newParserEnvironment()
.document(executionInput.getQuery()).parserOptions(parserOptions)
.locale(locale)
.build();
Document document = parser.parseDocument(parserEnvironment);
return ParseAndValidateResult.newResult().document(document).variables(executionInput.getVariables()).build();
} catch (InvalidSyntaxException e) {
return ParseAndValidateResult.newResult().syntaxException(e).variables(executionInput.getVariables()).build();
}
}
/**
* This can be called to validate a parsed graphql query.
*
* @param graphQLSchema the graphql schema to validate against
* @param parsedDocument the previously parsed document
* @param locale the current locale
*
* @return a result object that indicates how this operation went
*/
public static List<ValidationError> validate(@NonNull GraphQLSchema graphQLSchema, @NonNull Document parsedDocument, @NonNull Locale locale) {
return validate(graphQLSchema, parsedDocument, rule -> true, locale);
}
/**
* This can be called to validate a parsed graphql query, with the JVM default locale.
*
* @param graphQLSchema the graphql schema to validate against
* @param parsedDocument the previously parsed document
*
* @return a result object that indicates how this operation went
*/
public static List<ValidationError> validate(@NonNull GraphQLSchema graphQLSchema, @NonNull Document parsedDocument) {
return validate(graphQLSchema, parsedDocument, rule -> true, Locale.getDefault());
}
/**
* This can be called to validate a parsed graphql query.
*
* @param graphQLSchema the graphql schema to validate against
* @param parsedDocument the previously parsed document
* @param rulePredicate this predicate is used to decide what validation rules will be applied
* @param locale the current locale
*
* @return a result object that indicates how this operation went
*/
public static List<ValidationError> validate(@NonNull GraphQLSchema graphQLSchema, @NonNull Document parsedDocument, @NonNull Predicate<OperationValidationRule> rulePredicate, @NonNull Locale locale) {
return validate(graphQLSchema, parsedDocument, rulePredicate, locale, null);
}
/**
* This can be called to validate a parsed graphql query.
*
* @param graphQLSchema the graphql schema to validate against
* @param parsedDocument the previously parsed document
* @param rulePredicate this predicate is used to decide what validation rules will be applied
* @param locale the current locale
* @param limits optional query complexity limits to enforce
*
* @return a result object that indicates how this operation went
*/
public static List<ValidationError> validate(GraphQLSchema graphQLSchema, Document parsedDocument, Predicate<OperationValidationRule> rulePredicate, Locale locale, @Nullable QueryComplexityLimits limits) {
Validator validator = new Validator();
return validator.validateDocument(graphQLSchema, parsedDocument, rulePredicate, locale, limits);
}
/**
* This can be called to validate a parsed graphql query, with the JVM default locale.
*
* @param graphQLSchema the graphql schema to validate against
* @param parsedDocument the previously parsed document
* @param rulePredicate this predicate is used to decide what validation rules will be applied
*
* @return a result object that indicates how this operation went
*/
public static List<ValidationError> validate(@NonNull GraphQLSchema graphQLSchema, @NonNull Document parsedDocument, @NonNull Predicate<OperationValidationRule> rulePredicate) {
Validator validator = new Validator();
return validator.validateDocument(graphQLSchema, parsedDocument, rulePredicate, Locale.getDefault());
}
}