Skip to content

Commit

Permalink
[RFC] GraphQL Schema Definition Language (SDL) (#90)
Browse files Browse the repository at this point in the history
* [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
  • Loading branch information
leebyron authored Feb 8, 2018
1 parent 4ba1366 commit 593dd2c
Show file tree
Hide file tree
Showing 6 changed files with 929 additions and 190 deletions.
132 changes: 127 additions & 5 deletions spec/Appendix B -- Grammar Summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,15 @@ Note: Block string values are interpreted to exclude blank initial and trailing
lines and uniform indentation with {BlockStringValue()}.


## Query Document
## Document

Document : Definition+

Definition :
- ExecutableDefinition
- TypeSystemDefinition

ExecutableDefinition :
- OperationDefinition
- FragmentDefinition

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

Alias : Name :

Arguments : ( Argument+ )
Arguments[Const] : ( Argument[?Const]+ )

Argument : Name : Value
Argument[Const] : Name : Value[?Const]

FragmentSpread : ... FragmentName Directives?

Expand Down Expand Up @@ -176,6 +180,124 @@ NonNullType :
- NamedType !
- ListType !

Directives : Directive+
Directives[Const] : Directive[?Const]+

Directive[Const] : @ Name Arguments[?Const]?

TypeSystemDefinition :
- SchemaDefinition
- TypeDefinition
- TypeExtension
- DirectiveDefinition

SchemaDefinition : schema Directives[Const]? { OperationTypeDefinition+ }

OperationTypeDefinition : OperationType : NamedType

Description : StringValue

TypeDefinition :
- ScalarTypeDefinition
- ObjectTypeDefinition
- InterfaceTypeDefinition
- UnionTypeDefinition
- EnumTypeDefinition
- InputObjectTypeDefinition

TypeExtension :
- ScalarTypeExtension
- ObjectTypeExtension
- InterfaceTypeExtension
- UnionTypeExtension
- EnumTypeExtension
- InputObjectTypeExtension

ScalarTypeDefinition : Description? scalar Name Directives[Const]?

ScalarTypeExtension :
- extend scalar Name Directives[Const]

ObjectTypeDefinition : Description? type Name ImplementsInterfaces? Directives[Const]? FieldsDefinition?

ObjectTypeExtension :
- extend type Name ImplementsInterfaces? Directives[Const]? FieldsDefinition
- extend type Name ImplementsInterfaces? Directives[Const]
- extend type Name ImplementsInterfaces

ImplementsInterfaces :
- implements `&`? NamedType
- ImplementsInterfaces & NamedType

FieldsDefinition : { FieldDefinition+ }

FieldDefinition : Description? Name ArgumentsDefinition? : Type Directives[Const]?

ArgumentsDefinition : ( InputValueDefinition+ )

InputValueDefinition : Description? Name : Type DefaultValue? Directives[Const]?

InterfaceTypeDefinition : Description? interface Name Directives[Const]? FieldsDefinition?

InterfaceTypeExtension :
- extend interface Name Directives[Const]? FieldsDefinition
- extend interface Name Directives[Const]

UnionTypeDefinition : Description? union Name Directives[Const]? UnionMemberTypes?

UnionMemberTypes :
- = `|`? NamedType
- UnionMemberTypes | NamedType

UnionTypeExtension :
- extend union Name Directives[Const]? UnionMemberTypes
- extend union Name Directives[Const]

EnumTypeDefinition : Description? enum Name Directives[Const]? EnumValuesDefinition?

EnumValuesDefinition : { EnumValueDefinition+ }

EnumValueDefinition : Description? EnumValue Directives[Const]?

EnumTypeExtension :
- extend enum Name Directives[Const]? EnumValuesDefinition
- extend enum Name Directives[Const]

InputObjectTypeDefinition : Description? input Name Directives[Const]? InputFieldsDefinition?

InputFieldsDefinition : { InputValueDefinition+ }

InputObjectTypeExtension :
- extend input Name Directives[Const]? InputFieldsDefinition
- extend input Name Directives[Const]

DirectiveDefinition : Description? directive @ Name ArgumentsDefinition? on DirectiveLocations

DirectiveLocations :
- `|`? DirectiveLocation
- DirectiveLocations | DirectiveLocation

DirectiveLocation :
- ExecutableDirectiveLocation
- TypeSystemDirectiveLocation

ExecutableDirectiveLocation : one of
`QUERY`
`MUTATION`
`SUBSCRIPTION`
`FIELD`
`FRAGMENT_DEFINITION`
`FRAGMENT_SPREAD`
`INLINE_FRAGMENT`

Directive : @ Name Arguments?
TypeSystemDirectiveLocation : one of
`SCHEMA`
`SCALAR`
`OBJECT`
`FIELD_DEFINITION`
`ARGUMENT_DEFINITION`
`INTERFACE`
`UNION`
`ENUM`
`ENUM_VALUE`
`INPUT_OBJECT`
`INPUT_FIELD_DEFINITION`
60 changes: 36 additions & 24 deletions spec/Section 2 -- Language.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ WhiteSpace ::
White space is used to improve legibility of source text and act as separation
between tokens, and any amount of white space may appear before or after any
token. White space between tokens is not significant to the semantic meaning of
a GraphQL query document, however white space characters may appear within a
a GraphQL Document, however white space characters may appear within a
{String} or {Comment} token.

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

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

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

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


### Insignificant Commas
Expand All @@ -94,7 +94,7 @@ Comma :: ,

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

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

Tokens are later used as terminal symbols in a GraphQL query document syntactic
grammars.
Tokens are later used as terminal symbols in a GraphQL Document
syntactic grammars.


### Ignored Tokens
Expand Down Expand Up @@ -152,8 +152,8 @@ lacks the punctuation often used to describe mathematical expressions.

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

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

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


## Query Document
## Document

Document : Definition+

Definition :
- ExecutableDefinition
- TypeSystemDefinition

ExecutableDefinition :
- OperationDefinition
- FragmentDefinition

A GraphQL query document describes a complete file or request string received by
a GraphQL service. A document contains multiple definitions of Operations and
Fragments. GraphQL query documents are only executable by a server if they
contain an operation. However documents which do not contain operations may
still be parsed and validated to allow client to represent a single request
across many documents.
A GraphQL Document describes a complete file or request string operated on
by a GraphQL service or client. A document contains multiple definitions, either
executable or representative of a GraphQL type system.

Documents are only executable by a GraphQL service if they contain an
{OperationDefinition}, only contain {ExecutableDefinition} and do not contain
{TypeSystemDefinition}. However documents which do not contain
{OperationDefinition} or do contain {TypeSystemDefinition} may still be parsed
and validated to allow client tools to represent many GraphQL uses which may
appear across many individual files.

If a document contains only one operation, that operation may be unnamed or
If a Document contains only one operation, that operation may be unnamed or
represented in the shorthand form, which omits both the query keyword and
operation name. Otherwise, if a GraphQL query document contains multiple
operations, each operation must be named. When submitting a query document with
operation name. Otherwise, if a GraphQL Document contains multiple
operations, each operation must be named. When submitting a Document with
multiple operations to a GraphQL service, the name of the desired operation to
be executed must also be provided.

GraphQL services which only seek to provide GraphQL query execution may choose
to only include {ExecutableDefinition} and omit the {TypeSystemDefinition} rule
from {Definition}.


## Operations

Expand Down Expand Up @@ -318,9 +330,9 @@ unique identifier.

## Arguments

Arguments : ( Argument+ )
Arguments[Const] : ( Argument[?Const]+ )

Argument : Name : Value
Argument[Const] : Name : Value[?Const]

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


## Input Types
## Type References

Type :
- NamedType
Expand Down Expand Up @@ -1059,9 +1071,9 @@ Type : Type !

## Directives

Directives : Directive+
Directives[Const] : Directive[?Const]+

Directive : @ Name Arguments?
Directive[Const] : @ Name Arguments[?Const]?

Directives provide a way to describe alternate runtime execution and type
validation behavior in a GraphQL document.
Expand Down
Loading

0 comments on commit 593dd2c

Please sign in to comment.