Skip to content

Commit 8cbfcec

Browse files
Validate that the operation's root type is valid
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 vektah#221.
1 parent d3d9eb0 commit 8cbfcec

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)