Skip to content

Commit 0e3e4c2

Browse files
Validate that the operation's root type is valid (#225)
Turns out neither we (nor anyone else) were validating this, because the spec didn't say explicitly to validate it. So you could do `mutation { bogus }` even if the schema has no mutation types, or worse, any syntactically valid query if the schema is totally empty. In graphql/graphql-spec#955 I'm adding it to the spec, and in graphql/graphql-js#3592 someone else is adding it to graphql-js. So we should too, once those land! At that point we should also likely reimport the relevant tests, instead of the ones I wrote here, but I figured I'd put the PR up now so folks can review the non-test parts if you like. Fixes #221.
1 parent 6eec772 commit 0e3e4c2

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed

validator/imported/spec/schemas.yml

+1
Original file line numberDiff line numberDiff line change
@@ -487,3 +487,4 @@
487487
}
488488
489489
scalar Any
490+
- ""

validator/rules/known_root_type.go

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package validator
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/vektah/gqlparser/v2/ast"
7+
. "github.com/vektah/gqlparser/v2/validator"
8+
)
9+
10+
func init() {
11+
AddRule("KnownRootType", func(observers *Events, addError AddErrFunc) {
12+
// A query's root must be a valid type. Surprisingly, this isn't
13+
// checked anywhere else!
14+
observers.OnOperation(func(walker *Walker, operation *ast.OperationDefinition) {
15+
var def *ast.Definition
16+
switch operation.Operation {
17+
case ast.Query, "":
18+
def = walker.Schema.Query
19+
case ast.Mutation:
20+
def = walker.Schema.Mutation
21+
case ast.Subscription:
22+
def = walker.Schema.Subscription
23+
default:
24+
// This shouldn't even parse; if it did we probably need to
25+
// update this switch block to add the new operation type.
26+
panic(fmt.Sprintf(`got unknown operation type "%s"`, operation.Operation))
27+
}
28+
if def == nil {
29+
addError(
30+
Message(`Schema does not support operation type "%s"`, operation.Operation),
31+
At(operation.Position))
32+
}
33+
})
34+
})
35+
}
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
- name: Known root type
2+
rule: KnownRootType
3+
schema: 0
4+
query: |
5+
query { dog { name } }
6+
- name: Valid root type but not in schema
7+
rule: KnownRootType
8+
schema: 0
9+
query: |
10+
mutation { dog { name } }
11+
errors:
12+
- message: Schema does not support operation type "mutation"
13+
- name: Valid root type but schema is entirely empty
14+
rule: KnownRootType
15+
schema: 20
16+
query: |
17+
{ dog { name } }
18+
errors:
19+
- message: Schema does not support operation type "query"

0 commit comments

Comments
 (0)