Set Extensions for Type System Documents
This document specifics an alternative to the Type System Document for defining a set-compatible version of the type system of a GraphQL Schema.
It is common to need to treat schema documents as sets: we may want to merge two documents to create a “Composite Schema”, or you might want to know the intersection between documents to build products that work against all the provided GraphQL Services.
Any grammar not defined, but used, in this document is a reference to the grammar defined in the GraphQL Specification’s Grammar.
The key change to the grammar: every location in the schema that can have a directive now can also be an Extension.
To put it another way, if a location in the Schema can be defined by a Schema Coordinate, then it can exist in the Set Type System in an extend representation. Additionally, the root schema has an extend representation, because it can apply set operations.
1Set Type System
1.1Schema
1.1.1Schema Extension
SetSchemaDefinition and SetSchemaExtension are grammatically identical to the Schema in the GraphQL Specification.
1.2Types
1.2.1Type Extensions
1.3Scalars
SetScalarTypeDefinition and SetScalarTypeExtension are gramatically identical to the Scalars Specification.
1.3.1Scalar Extensions
1.4Objects
1.4.1Object Extensions
1.5Fields
1.5.1Field Extensions
It is possible for the type definition of a field to only be present in that field’s extension. Likewise, we need to be able to extend a field (like deprecating it) with a guarantee that the field’s type will not change through the extension.
Field extensions are different from fields defined by a type extension. The below is valid syntax:
graphql field-extension extend type Person { extend age @deprecated name } type Business { extend name @deprecated } To become a valid GraphQL Spec document, the above would need to be union‘d with a document like:
graphql field-extension-merge type Person { age: Int extend name: String @deprecated } extend type Business { name: String }
resulting in:
graphql field-extension-union type Person { age: Int @deprecated name: String @deprecated } type Business { name: String @deprecated } which is now a valid GraphQL Type System Document.
The syntax of allowing field definitions without a type definition enables tooling, such as diff tools, to have a valid syntax for how a schema is evolving, even if the semantic meaning of the syntax would not produce a valid GraphQL Schema.
1.5.2Field Arguments
1.5.3Input Values
1.5.4Input Value Extensions
Similar to Field Definitions and Extensions, Input Value Definitions and Extensions cannot may elide the input value’s type.
1.6Unions
1.6.1Union Extensions
SetUntionTypeExtension is gramatically identical to the Unions in the GraphQL Specification.
1.7Enums
1.7.1Enum Values
1.7.2Enum Extensions
1.8Input Objects
1.9Input Object Extensions
1.10Directives
| QUERY |
| MUTATION |
| SUBSCRIPTION |
| FIELD |
| FRAGMENT_DEFINITION |
| FRAGMENT_SPREAD |
| INLINE_FRAGMENT |
| VARIABLE_DEFINITION |
| SCHEMA |
| SCALAR |
| OBJECT |
| FIELD_DEFINITION |
| ARGUMENT_DEFINITION |
| INTERFACE |
| UNION |
| ENUM |
| ENUM_VALUE |
| INPUT_OBJECT |
| INPUT_FIELD_DEFINITION |
| DIRECTIVE_DEFINITION |
1.10.1Directive Extensions
2Set Operations
With the provided syntax, we can create set operations
union, or ∪ (also known as merge or set addition).unionis associative and commutative, much like addition.intersect, or ∩.exclude, or , or – (also known as difference or set subtraction).excludeis neither associative nor commutative, much like subtraction.
2.1Union
type A implements X {
field(arg: Int): String
}
union graphql type A @directive { field(arg: Int!): String! } will result in: type A implements X @directive { field(arg: Int!): String }
If a union could not possibly be commutative, i.e. the order of set union would affect the result, then the union operation should return a UnionError. The type of A.field below cannot be determined. type A { field: Int! } union type A { field: String! }
2.2Exclude
2.3Intersect
A intersect B = A exclude (A exclude B).
intersect is defined by the application of exclude.
3Appendix: Grammar Summary
| QUERY |
| MUTATION |
| SUBSCRIPTION |
| FIELD |
| FRAGMENT_DEFINITION |
| FRAGMENT_SPREAD |
| INLINE_FRAGMENT |
| VARIABLE_DEFINITION |
| SCHEMA |
| SCALAR |
| OBJECT |
| FIELD_DEFINITION |
| ARGUMENT_DEFINITION |
| INTERFACE |
| UNION |
| ENUM |
| ENUM_VALUE |
| INPUT_OBJECT |
| INPUT_FIELD_DEFINITION |
| DIRECTIVE_DEFINITION |
§Index
- DirectiveLocation
- DirectiveLocations
- Example
- ExecutableDirectiveLocation
- ImplementsInterfaces
- InputObjectTypeDefinition
- InputObjectTypeExtension
- RootOperationTypeDefinition
- SetArgumentsDefinition
- SetArgumentsDefinitionOrExtension
- SetDirectiveDefinition
- SetDirectiveExtension
- SetEnumTypeDefinition
- SetEnumTypeExtension
- SetEnumValueDefinition
- SetEnumValueDefinitionOrExtension
- SetEnumValueExtension
- SetEnumValuesDefinitionOrExtension
- SetFieldDefinition
- SetFieldDefinitionOrExtension
- SetFieldExtension
- SetFieldsDefinitionOrExtension
- SetInputFieldsDefinition
- SetInputFieldsDefinitionOrExtension
- SetInputObjectTypeDefinition
- SetInputObjectTypeExtension
- SetInputValueDefinition
- SetInputValueDefinitionOrExtension
- SetInputValueExtension
- SetInterfaceTypeDefinition
- SetInterfaceTypeExtension
- SetObjectTypeDefinition
- SetObjectTypeExtension
- SetScalarTypeDefinition
- SetScalarTypeExtension
- SetSchemaDefinition
- SetSchemaExtension
- SetTypeDefinition
- SetTypeExtension
- SetTypeSystemDefinition
- SetTypeSystemDefinitionOrExtension
- SetTypeSystemDocument
- SetTypeSystemExtension
- SetTypeSystemExtensionDocument
- SetUnionTypeDefinition
- SetUnionTypeExtension
- TypeSystemDirectiveLocation
- UnionMemberTypes