Validate schema root operation types - #876
Conversation
d0584b5 to
1236982
Compare
1236982 to
5766d24
Compare
|
Rebased onto current main. This will fail the build until #899 lands: |
There was a problem hiding this comment.
Very nice. Thanks! There are some cases where an invalid schema could still be made (type Query { foo: Int } extend schema { query: Undefined } or extend schema { query: Bar }; scalar Bar), but that seems very unlikely to actually occur. So I'm OK merging like this
5766d24 to
7239903
Compare
Sounds like a good enhancement to be covered by a future PR 👍 |
|
@hugo-vrijswijk I took the liberty and filed #903 so it's not lost |
Fixes #174.
Problem
A schema with no
queryroot type — either because it has notype Queryat all and no explicitschema { }block, or because an explicitschema { }block references a root type that doesn't exist — currently either:NoSuchElementExceptionthe first time.queryTypeis accessed (e.g. on the first query execution), orTypeReffor an undefinedmutation/subscriptionroot type, sinceschema { }root-type references were never existence-checked the way ordinary field/type references are.Per the GraphQL spec, "Root Operation Types":
This should be a schema validation error, not a runtime crash or silent bad state.
Fix
Adds
SchemaValidator.validateRootTypes, wired into the existingvalidateSchemachain right aftervalidateReferences. For each ofquery(mandatory),mutation(optional),subscription(optional):No 'query' root operation type in schemaUndefined type '<name>' specified as '<op>' root operation typeType '<name>' specified as '<op>' root operation type is not an object typeBecause both the
schema"""..."""compile-time macro and the runtimeSchema(string)constructor share the sameSchemaParser → validateSchemapipeline, this closes the gap at construction time for both entry points. No changes needed toqueryType/mutationType/subscriptionTypethemselves.Test plan
SchemaSuite.scala, one per error path (missing query, dangling reference, non-object root type).type Query { foo: Int }.