Skip to content

Commit

Permalink
Validate that the operation's root type is valid (#225)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
benjaminjkraft authored Jun 6, 2022
1 parent 6eec772 commit 0e3e4c2
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 0 deletions.
1 change: 1 addition & 0 deletions validator/imported/spec/schemas.yml
Original file line number Diff line number Diff line change
Expand Up @@ -487,3 +487,4 @@
}
scalar Any
- ""
35 changes: 35 additions & 0 deletions validator/rules/known_root_type.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package validator

import (
"fmt"

"github.com/vektah/gqlparser/v2/ast"
. "github.com/vektah/gqlparser/v2/validator"
)

func init() {
AddRule("KnownRootType", func(observers *Events, addError AddErrFunc) {
// A query's root must be a valid type. Surprisingly, this isn't
// checked anywhere else!
observers.OnOperation(func(walker *Walker, operation *ast.OperationDefinition) {
var def *ast.Definition
switch operation.Operation {
case ast.Query, "":
def = walker.Schema.Query
case ast.Mutation:
def = walker.Schema.Mutation
case ast.Subscription:
def = walker.Schema.Subscription
default:
// This shouldn't even parse; if it did we probably need to
// update this switch block to add the new operation type.
panic(fmt.Sprintf(`got unknown operation type "%s"`, operation.Operation))
}
if def == nil {
addError(
Message(`Schema does not support operation type "%s"`, operation.Operation),
At(operation.Position))
}
})
})
}
19 changes: 19 additions & 0 deletions validator/spec/KnownRootTypeRule.spec.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
- name: Known root type
rule: KnownRootType
schema: 0
query: |
query { dog { name } }
- name: Valid root type but not in schema
rule: KnownRootType
schema: 0
query: |
mutation { dog { name } }
errors:
- message: Schema does not support operation type "mutation"
- name: Valid root type but schema is entirely empty
rule: KnownRootType
schema: 20
query: |
{ dog { name } }
errors:
- message: Schema does not support operation type "query"

0 comments on commit 0e3e4c2

Please sign in to comment.