Skip to content

Commit 593dd2c

Browse files
authored
[RFC] GraphQL Schema Definition Language (SDL) (#90)
* [RFC] GraphQL IDL additions This adds the type definition syntax to the GraphQL specification. * Add directives to all schema definition forms * expose more in example directive * Include more directive locations * Include deprecated directive * Note on omission of schema definition * Explicit ObjectTypeExtension grammar to support extending without adding fields * Ensure directives cannot reference variables in SDL * grammar * Remove duplicate EnumValue * First class descriptions * Minor wording change about markdown and TSL -> SDL * Add validation rule that executable documents cannot include SDL * Move extend keyword * Order of sections * Move language definitions into Type System section * Fix type reference header and comments * Add more examples of descriptions * Grammar * Include optional leading bar for unions & directive locations. Merging and closing #323 * Allow partial definitions (as @OlegIlyenko suggests) while legitimizing the use case by allowing type extensions for all type kinds, allowing at least the addition of new directives to any existing type. * Consistent plural usage in grammar nt rules * Remove ambiguous "may not" and explicitly state objects may implement interfaces via extensions * Extract ExecutableDefinition into a separate gramatical rule * Address review from @vergenzt * Use `&` to separate implemented interfaces, simplify grammar definitions * Fix reference in grammar summary * Fix reference to UnionMemberTypes
1 parent 4ba1366 commit 593dd2c

6 files changed

+929
-190
lines changed

spec/Appendix B -- Grammar Summary.md

Lines changed: 127 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,15 @@ Note: Block string values are interpreted to exclude blank initial and trailing
8989
lines and uniform indentation with {BlockStringValue()}.
9090

9191

92-
## Query Document
92+
## Document
9393

9494
Document : Definition+
9595

9696
Definition :
97+
- ExecutableDefinition
98+
- TypeSystemDefinition
99+
100+
ExecutableDefinition :
97101
- OperationDefinition
98102
- FragmentDefinition
99103

@@ -114,9 +118,9 @@ Field : Alias? Name Arguments? Directives? SelectionSet?
114118

115119
Alias : Name :
116120

117-
Arguments : ( Argument+ )
121+
Arguments[Const] : ( Argument[?Const]+ )
118122

119-
Argument : Name : Value
123+
Argument[Const] : Name : Value[?Const]
120124

121125
FragmentSpread : ... FragmentName Directives?
122126

@@ -176,6 +180,124 @@ NonNullType :
176180
- NamedType !
177181
- ListType !
178182

179-
Directives : Directive+
183+
Directives[Const] : Directive[?Const]+
184+
185+
Directive[Const] : @ Name Arguments[?Const]?
186+
187+
TypeSystemDefinition :
188+
- SchemaDefinition
189+
- TypeDefinition
190+
- TypeExtension
191+
- DirectiveDefinition
192+
193+
SchemaDefinition : schema Directives[Const]? { OperationTypeDefinition+ }
194+
195+
OperationTypeDefinition : OperationType : NamedType
196+
197+
Description : StringValue
198+
199+
TypeDefinition :
200+
- ScalarTypeDefinition
201+
- ObjectTypeDefinition
202+
- InterfaceTypeDefinition
203+
- UnionTypeDefinition
204+
- EnumTypeDefinition
205+
- InputObjectTypeDefinition
206+
207+
TypeExtension :
208+
- ScalarTypeExtension
209+
- ObjectTypeExtension
210+
- InterfaceTypeExtension
211+
- UnionTypeExtension
212+
- EnumTypeExtension
213+
- InputObjectTypeExtension
214+
215+
ScalarTypeDefinition : Description? scalar Name Directives[Const]?
216+
217+
ScalarTypeExtension :
218+
- extend scalar Name Directives[Const]
219+
220+
ObjectTypeDefinition : Description? type Name ImplementsInterfaces? Directives[Const]? FieldsDefinition?
221+
222+
ObjectTypeExtension :
223+
- extend type Name ImplementsInterfaces? Directives[Const]? FieldsDefinition
224+
- extend type Name ImplementsInterfaces? Directives[Const]
225+
- extend type Name ImplementsInterfaces
226+
227+
ImplementsInterfaces :
228+
- implements `&`? NamedType
229+
- ImplementsInterfaces & NamedType
230+
231+
FieldsDefinition : { FieldDefinition+ }
232+
233+
FieldDefinition : Description? Name ArgumentsDefinition? : Type Directives[Const]?
234+
235+
ArgumentsDefinition : ( InputValueDefinition+ )
236+
237+
InputValueDefinition : Description? Name : Type DefaultValue? Directives[Const]?
238+
239+
InterfaceTypeDefinition : Description? interface Name Directives[Const]? FieldsDefinition?
240+
241+
InterfaceTypeExtension :
242+
- extend interface Name Directives[Const]? FieldsDefinition
243+
- extend interface Name Directives[Const]
244+
245+
UnionTypeDefinition : Description? union Name Directives[Const]? UnionMemberTypes?
246+
247+
UnionMemberTypes :
248+
- = `|`? NamedType
249+
- UnionMemberTypes | NamedType
250+
251+
UnionTypeExtension :
252+
- extend union Name Directives[Const]? UnionMemberTypes
253+
- extend union Name Directives[Const]
254+
255+
EnumTypeDefinition : Description? enum Name Directives[Const]? EnumValuesDefinition?
256+
257+
EnumValuesDefinition : { EnumValueDefinition+ }
258+
259+
EnumValueDefinition : Description? EnumValue Directives[Const]?
260+
261+
EnumTypeExtension :
262+
- extend enum Name Directives[Const]? EnumValuesDefinition
263+
- extend enum Name Directives[Const]
264+
265+
InputObjectTypeDefinition : Description? input Name Directives[Const]? InputFieldsDefinition?
266+
267+
InputFieldsDefinition : { InputValueDefinition+ }
268+
269+
InputObjectTypeExtension :
270+
- extend input Name Directives[Const]? InputFieldsDefinition
271+
- extend input Name Directives[Const]
272+
273+
DirectiveDefinition : Description? directive @ Name ArgumentsDefinition? on DirectiveLocations
274+
275+
DirectiveLocations :
276+
- `|`? DirectiveLocation
277+
- DirectiveLocations | DirectiveLocation
278+
279+
DirectiveLocation :
280+
- ExecutableDirectiveLocation
281+
- TypeSystemDirectiveLocation
282+
283+
ExecutableDirectiveLocation : one of
284+
`QUERY`
285+
`MUTATION`
286+
`SUBSCRIPTION`
287+
`FIELD`
288+
`FRAGMENT_DEFINITION`
289+
`FRAGMENT_SPREAD`
290+
`INLINE_FRAGMENT`
180291

181-
Directive : @ Name Arguments?
292+
TypeSystemDirectiveLocation : one of
293+
`SCHEMA`
294+
`SCALAR`
295+
`OBJECT`
296+
`FIELD_DEFINITION`
297+
`ARGUMENT_DEFINITION`
298+
`INTERFACE`
299+
`UNION`
300+
`ENUM`
301+
`ENUM_VALUE`
302+
`INPUT_OBJECT`
303+
`INPUT_FIELD_DEFINITION`

spec/Section 2 -- Language.md

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ WhiteSpace ::
4545
White space is used to improve legibility of source text and act as separation
4646
between tokens, and any amount of white space may appear before or after any
4747
token. White space between tokens is not significant to the semantic meaning of
48-
a GraphQL query document, however white space characters may appear within a
48+
a GraphQL Document, however white space characters may appear within a
4949
{String} or {Comment} token.
5050

5151
Note: GraphQL intentionally does not consider Unicode "Zs" category characters
@@ -62,7 +62,7 @@ LineTerminator ::
6262

6363
Like white space, line terminators are used to improve the legibility of source
6464
text, any amount may appear before or after any other token and have no
65-
significance to the semantic meaning of a GraphQL query document. Line
65+
significance to the semantic meaning of a GraphQL Document. Line
6666
terminators are not found within any other token.
6767

6868
Note: Any error reporting which provide the line number in the source of the
@@ -84,8 +84,8 @@ comment always consists of all code points starting with the {`#`} character up
8484
to but not including the line terminator.
8585

8686
Comments behave like white space and may appear after any token, or before a
87-
line terminator, and have no significance to the semantic meaning of a GraphQL
88-
query document.
87+
line terminator, and have no significance to the semantic meaning of a
88+
GraphQL Document.
8989

9090

9191
### Insignificant Commas
@@ -94,7 +94,7 @@ Comma :: ,
9494

9595
Similar to white space and line terminators, commas ({`,`}) are used to improve
9696
the legibility of source text and separate lexical tokens but are otherwise
97-
syntactically and semantically insignificant within GraphQL query documents.
97+
syntactically and semantically insignificant within GraphQL Documents.
9898

9999
Non-significant comma characters ensure that the absence or presence of a comma
100100
does not meaningfully alter the interpreted syntax of the document, as this can
@@ -115,8 +115,8 @@ Token ::
115115
A GraphQL document is comprised of several kinds of indivisible lexical tokens
116116
defined here in a lexical grammar by patterns of source Unicode characters.
117117

118-
Tokens are later used as terminal symbols in a GraphQL query document syntactic
119-
grammars.
118+
Tokens are later used as terminal symbols in a GraphQL Document
119+
syntactic grammars.
120120

121121

122122
### Ignored Tokens
@@ -152,8 +152,8 @@ lacks the punctuation often used to describe mathematical expressions.
152152

153153
Name :: /[_A-Za-z][_0-9A-Za-z]*/
154154

155-
GraphQL query documents are full of named things: operations, fields, arguments,
156-
directives, fragments, and variables. All names must follow the same
155+
GraphQL Documents are full of named things: operations, fields, arguments,
156+
types, directives, fragments, and variables. All names must follow the same
157157
grammatical form.
158158

159159
Names in GraphQL are case-sensitive. That is to say `name`, `Name`, and `NAME`
@@ -164,28 +164,40 @@ Names in GraphQL are limited to this <acronym>ASCII</acronym> subset of possible
164164
characters to support interoperation with as many other systems as possible.
165165

166166

167-
## Query Document
167+
## Document
168168

169169
Document : Definition+
170170

171171
Definition :
172+
- ExecutableDefinition
173+
- TypeSystemDefinition
174+
175+
ExecutableDefinition :
172176
- OperationDefinition
173177
- FragmentDefinition
174178

175-
A GraphQL query document describes a complete file or request string received by
176-
a GraphQL service. A document contains multiple definitions of Operations and
177-
Fragments. GraphQL query documents are only executable by a server if they
178-
contain an operation. However documents which do not contain operations may
179-
still be parsed and validated to allow client to represent a single request
180-
across many documents.
179+
A GraphQL Document describes a complete file or request string operated on
180+
by a GraphQL service or client. A document contains multiple definitions, either
181+
executable or representative of a GraphQL type system.
182+
183+
Documents are only executable by a GraphQL service if they contain an
184+
{OperationDefinition}, only contain {ExecutableDefinition} and do not contain
185+
{TypeSystemDefinition}. However documents which do not contain
186+
{OperationDefinition} or do contain {TypeSystemDefinition} may still be parsed
187+
and validated to allow client tools to represent many GraphQL uses which may
188+
appear across many individual files.
181189

182-
If a document contains only one operation, that operation may be unnamed or
190+
If a Document contains only one operation, that operation may be unnamed or
183191
represented in the shorthand form, which omits both the query keyword and
184-
operation name. Otherwise, if a GraphQL query document contains multiple
185-
operations, each operation must be named. When submitting a query document with
192+
operation name. Otherwise, if a GraphQL Document contains multiple
193+
operations, each operation must be named. When submitting a Document with
186194
multiple operations to a GraphQL service, the name of the desired operation to
187195
be executed must also be provided.
188196

197+
GraphQL services which only seek to provide GraphQL query execution may choose
198+
to only include {ExecutableDefinition} and omit the {TypeSystemDefinition} rule
199+
from {Definition}.
200+
189201

190202
## Operations
191203

@@ -318,9 +330,9 @@ unique identifier.
318330

319331
## Arguments
320332

321-
Arguments : ( Argument+ )
333+
Arguments[Const] : ( Argument[?Const]+ )
322334

323-
Argument : Name : Value
335+
Argument[Const] : Name : Value[?Const]
324336

325337
Fields are conceptually functions which return values, and occasionally accept
326338
arguments which alter their behavior. These arguments often map directly to
@@ -1016,7 +1028,7 @@ a variable is referenced in a fragment and is included by an operation that does
10161028
not define that variable, the operation cannot be executed.
10171029

10181030

1019-
## Input Types
1031+
## Type References
10201032

10211033
Type :
10221034
- NamedType
@@ -1059,9 +1071,9 @@ Type : Type !
10591071

10601072
## Directives
10611073

1062-
Directives : Directive+
1074+
Directives[Const] : Directive[?Const]+
10631075

1064-
Directive : @ Name Arguments?
1076+
Directive[Const] : @ Name Arguments[?Const]?
10651077

10661078
Directives provide a way to describe alternate runtime execution and type
10671079
validation behavior in a GraphQL document.

0 commit comments

Comments
 (0)