Skip to content

Commit fb3402f

Browse files
committed
make graphql.Do() aware custom validation rule
add "ValidationRules" field to graphql.Params, to be able to customize validation rules per query.
1 parent 9441c49 commit fb3402f

File tree

3 files changed

+68
-1
lines changed

3 files changed

+68
-1
lines changed

go.mod

+2
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
module github.com/graphql-go/graphql
2+
3+
go 1.14

graphql.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ type Params struct {
2828
// one operation.
2929
OperationName string
3030

31+
// ValidationRules is for overriding rules of document validation. Default
32+
// SpecifiedRules are ignored when specified this option other than nil.
33+
// So it would be better that combining your rules with SpecifiedRules to
34+
// fill this.
35+
ValidationRules []ValidationRuleFn
36+
3137
// Context may be provided to pass application-specific per-request
3238
// information to resolve functions.
3339
Context context.Context
@@ -84,7 +90,7 @@ func Do(p Params) *Result {
8490
}
8591

8692
// validate document
87-
validationResult := ValidateDocument(&p.Schema, AST, nil)
93+
validationResult := ValidateDocument(&p.Schema, AST, p.ValidationRules)
8894

8995
if !validationResult.IsValid {
9096
// run validation finish functions for extensions

graphql_test.go

+59
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import (
66
"testing"
77

88
"github.com/graphql-go/graphql"
9+
"github.com/graphql-go/graphql/language/ast"
10+
"github.com/graphql-go/graphql/language/kinds"
11+
"github.com/graphql-go/graphql/language/visitor"
912
"github.com/graphql-go/graphql/testutil"
1013
)
1114

@@ -268,3 +271,59 @@ func TestEmptyStringIsNotNull(t *testing.T) {
268271
t.Errorf("wrong result, query: %v, graphql result diff: %v", query, testutil.Diff(expected, result))
269272
}
270273
}
274+
275+
func TestQueryWithCustomRule(t *testing.T) {
276+
// Test graphql.Do() with custom rule, it extracts query name from each
277+
// Tests.
278+
ruleN := len(graphql.SpecifiedRules)
279+
rules := make([]graphql.ValidationRuleFn, ruleN+1)
280+
copy(rules[:ruleN], graphql.SpecifiedRules)
281+
282+
var (
283+
queryFound bool
284+
queryName string
285+
)
286+
rules[ruleN] = func(context *graphql.ValidationContext) *graphql.ValidationRuleInstance {
287+
return &graphql.ValidationRuleInstance{
288+
VisitorOpts: &visitor.VisitorOptions{
289+
KindFuncMap: map[string]visitor.NamedVisitFuncs{
290+
kinds.OperationDefinition: {
291+
Enter: func(p visitor.VisitFuncParams) (string, interface{}) {
292+
od, ok := p.Node.(*ast.OperationDefinition)
293+
if ok && od.Operation == "query" {
294+
queryFound = true
295+
if od.Name != nil {
296+
queryName = od.Name.Value
297+
}
298+
}
299+
return visitor.ActionNoChange, nil
300+
},
301+
},
302+
},
303+
},
304+
}
305+
}
306+
307+
expectedNames := []string{
308+
"HeroNameQuery",
309+
"HeroNameAndFriendsQuery",
310+
"HumanByIdQuery",
311+
}
312+
313+
for i, test := range Tests {
314+
queryFound, queryName = false, ""
315+
params := graphql.Params{
316+
Schema: test.Schema,
317+
RequestString: test.Query,
318+
VariableValues: test.Variables,
319+
ValidationRules: rules,
320+
}
321+
testGraphql(test, params, t)
322+
if !queryFound {
323+
t.Fatal("can't detect \"query\" operation by validation rule")
324+
}
325+
if queryName != expectedNames[i] {
326+
t.Fatalf("unexpected query name: want=%s got=%s", queryName, expectedNames)
327+
}
328+
}
329+
}

0 commit comments

Comments
 (0)