-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgraphql_validation_example.go
More file actions
132 lines (104 loc) · 2.75 KB
/
Copy pathgraphql_validation_example.go
File metadata and controls
132 lines (104 loc) · 2.75 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
package graph
// This file contains examples of how to create custom validation rules using BaseRule
/*
Example 1: Simple custom rule
type MyCustomRule struct {
BaseRule
maxValue int
}
func NewMyCustomRule(maxValue int) ValidationRule {
return &MyCustomRule{
BaseRule: NewBaseRule("MyCustomRule"),
maxValue: maxValue,
}
}
func (r *MyCustomRule) Validate(ctx *ValidationContext) error {
// Your validation logic here
if someCondition {
return r.NewError("simple error message")
}
if anotherCondition {
return r.NewErrorf("formatted error: value=%d, max=%d", value, r.maxValue)
}
return nil
}
Example 2: Rule that uses AST visitor
type BlockMutationRule struct {
BaseRule
blockedMutations map[string]bool
}
func NewBlockMutationRule(mutations ...string) ValidationRule {
rule := &BlockMutationRule{
BaseRule: NewBaseRule("BlockMutationRule"),
blockedMutations: make(map[string]bool),
}
for _, m := range mutations {
rule.blockedMutations[m] = true
}
return rule
}
func (r *BlockMutationRule) Validate(ctx *ValidationContext) error {
visitor := &ASTVisitor{
EnterField: func(field *ast.Field, vctx *ValidationContext) error {
if field.Name != nil && r.blockedMutations[field.Name.Value] {
return r.NewErrorf("mutation '%s' is blocked", field.Name.Value)
}
return nil
},
}
return traverseAST(ctx.Document, visitor, ctx)
}
Example 3: Rule that checks authentication context
type RequireEmailVerifiedRule struct {
BaseRule
}
func NewRequireEmailVerifiedRule() ValidationRule {
return &RequireEmailVerifiedRule{
BaseRule: NewBaseRule("RequireEmailVerifiedRule"),
}
}
func (r *RequireEmailVerifiedRule) Validate(ctx *ValidationContext) error {
if ctx.Auth == nil || !ctx.Auth.Authenticated {
return r.NewError("authentication required")
}
// Check custom claim
emailVerified, ok := ctx.Auth.Claims["email_verified"].(bool)
if !ok || !emailVerified {
return r.NewError("email verification required")
}
return nil
}
Example 4: Conditional rule
type BusinessHoursOnlyRule struct {
BaseRule
startHour int
endHour int
}
func NewBusinessHoursOnlyRule(start, end int) ValidationRule {
return &BusinessHoursOnlyRule{
BaseRule: NewBaseRule("BusinessHoursOnlyRule"),
startHour: start,
endHour: end,
}
}
func (r *BusinessHoursOnlyRule) Validate(ctx *ValidationContext) error {
now := time.Now()
hour := now.Hour()
if hour < r.startHour || hour >= r.endHour {
return r.NewErrorf("API only available during business hours (%d:00-%d:00)", r.startHour, r.endHour)
}
return nil
}
Example 5: Using Enable/Disable
rule := NewMyCustomRule(100)
// Disable rule conditionally
if env == "development" {
rule.Disable()
}
// Re-enable later
rule.Enable()
// Check if enabled
if rule.Enabled() {
// Will be validated
}
*/