From 38616cc645ce8ec739a82a059c54c1c129cb3383 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Thu, 17 Sep 2020 02:17:07 -0700 Subject: [PATCH 01/46] Add Schema Coordinates RFC --- spec/Appendix C -- Schema Coordinates.md | 168 +++++++++++++++++++++++ spec/GraphQL.md | 2 + 2 files changed, 170 insertions(+) create mode 100644 spec/Appendix C -- Schema Coordinates.md diff --git a/spec/Appendix C -- Schema Coordinates.md b/spec/Appendix C -- Schema Coordinates.md new file mode 100644 index 000000000..530f67aec --- /dev/null +++ b/spec/Appendix C -- Schema Coordinates.md @@ -0,0 +1,168 @@ +# Appendix: Schema Coordinates + +Schema Coordinates are human readable strings that uniquely identify an element defined in a GraphQL Schema. + +## Definition + +SchemaCoordinates : + - TypeName FieldSpecifier? + - InterfaceName FieldSpecifier? + - EnumName EnumValueSpecifier? + - @ DirectiveName ArgumentSpecifier? + - UnionName + +FieldSpecifier : + - . FieldName ArgumentSpecifier? + +ArgumentSpecifier : + - ( ArgumentName ) + +EnumValueSpecifier : + - . EnumValue + +## Examples + +This section shows example coordinates for the possible schema element types this syntax covers. + +All examples below will assume the following schema: + +```graphql example +directive @private(scope: String!) on FIELD + +interface Address { + city: String +} + +type User implements Address { + name: String + reviewCount: Int + friends: [User] + email: String @private(scope: 'loggedIn') + city: String +} + +type Business implements Address { + name: String + address: String + rating: Int + city: String +} + +union Entity = User | Business + +enum SearchFilter { + OPEN_NOW + DELIVERS_TAKEOUT + VEGETARIAN_MENU +} + +type Query { + searchBusiness(name: String!, filter: SearchFilter): Business +} +``` + +**Selecting a Type** + +Schema Coordinates for the `Business` type: + +```example +Business +``` + +Schema Coordinates for the `User` type: + +```example +User +``` + +**Selecting a Field on a Type** + +Schema Coordinates for the `name` field on the `Business` type: + +```example +Business.name +``` + +Schema Coordinates for the `name` field on the `User` type: + +```example +User.name +``` + +**Selecting an Argument on a Field** + +Schema Coordinates for the `name` argument on the `searchBusiness` field on the `Query` type: + +```example +Query.searchBusiness(name) +``` + +Schema Coordinates for the `filter` argument on the `searchBusiness` field on the `Query` type: + +```example +Query.searchBusiness(filter) +``` + +**Selecting an Enum** + +Schema Coordinates for the `SearchFilter` enum: + +```example +SearchFilter +``` + +**Selecting an Enum Value** + +Schema Coordinates for the `OPEN_NOW` value of the`SearchFilter` enum: + +```example +SearchFilter.OPEN_NOW +``` + +**Selecting a Directive Definition** + +Schema Coordinates for the `@private` directive definition: + +```example +@private +``` + +**Selecting a Directive Definition Argument** + +Schema Coordinates for the `scope` argument on the `@private` directive definition: + +```example +@private(scope) +``` + +**Selecting an Interface** + +Schema Coordinates for the `Address` interface: + +```example +Address +``` + +**Selecting a Field on an Interface** + +Schema Coordinates for the `city` field on the `Address` interface: + +```example +Address.city +``` + +**Selecting a Union** + +Schema Coordinates for the `Entity` union definition: + +```example +Entity +``` + +You may not select members inside a union definition. + +```graphql counter-example +Entity.Business +``` + +In such cases, you may wish to [select the type directly](#sec-Examples.Selecting-a-Type) instead. \ No newline at end of file diff --git a/spec/GraphQL.md b/spec/GraphQL.md index fad6bcdbe..aabff200e 100644 --- a/spec/GraphQL.md +++ b/spec/GraphQL.md @@ -139,3 +139,5 @@ Note: This is an example of a non-normative note. # [Appendix: Notation Conventions](Appendix%20A%20--%20Notation%20Conventions.md) # [Appendix: Grammar Summary](Appendix%20B%20--%20Grammar%20Summary.md) + +# [Appendix: Schema Coordinates](Appendix%20C%20--%20Schema%20Coordinates.md) From 45fb46cebd9035c98677dd0cb3f22e8891130ce7 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Tue, 17 Nov 2020 22:56:48 -0800 Subject: [PATCH 02/46] Update schema coordinates spec edit - Make examples table - Tweak the grammar definition --- spec/Appendix C -- Schema Coordinates.md | 125 +++++------------------ 1 file changed, 25 insertions(+), 100 deletions(-) diff --git a/spec/Appendix C -- Schema Coordinates.md b/spec/Appendix C -- Schema Coordinates.md index 530f67aec..aea21069e 100644 --- a/spec/Appendix C -- Schema Coordinates.md +++ b/spec/Appendix C -- Schema Coordinates.md @@ -5,17 +5,20 @@ Schema Coordinates are human readable strings that uniquely identify an element ## Definition SchemaCoordinates : - - TypeName FieldSpecifier? - - InterfaceName FieldSpecifier? + - TypeDefinitionName FieldSpecifier? - EnumName EnumValueSpecifier? - @ DirectiveName ArgumentSpecifier? - UnionName +TypeDefinitionName: + - ObjectTypeName + - InterfaceTypeName + FieldSpecifier : - . FieldName ArgumentSpecifier? ArgumentSpecifier : - - ( ArgumentName ) + - ( ArgumentName: ) EnumValueSpecifier : - . EnumValue @@ -61,108 +64,30 @@ type Query { } ``` -**Selecting a Type** - -Schema Coordinates for the `Business` type: - -```example -Business -``` - -Schema Coordinates for the `User` type: - -```example -User -``` - -**Selecting a Field on a Type** - -Schema Coordinates for the `name` field on the `Business` type: - -```example -Business.name -``` - -Schema Coordinates for the `name` field on the `User` type: +The following table demonstrates how to select various kinds of schema elements: -```example -User.name -``` - -**Selecting an Argument on a Field** - -Schema Coordinates for the `name` argument on the `searchBusiness` field on the `Query` type: - -```example -Query.searchBusiness(name) -``` - -Schema Coordinates for the `filter` argument on the `searchBusiness` field on the `Query` type: - -```example -Query.searchBusiness(filter) -``` - -**Selecting an Enum** - -Schema Coordinates for the `SearchFilter` enum: - -```example -SearchFilter -``` +| Example | Description | +| ------------------------------ | ------------------------------------------------------------------- | +| `Business` | `Business` type | +| `User` | `User` type | +| `Business.name` | `name` field on the `Business` type | +| `User.name` | `name` field on the `User` type | +| `Query.searchBusiness(name:)` | `name` argument on the `searchBusiness` field on the `Query` type | +| `Query.searchBusiness(filter:)`| `filter` argument on the `searchBusiness` field on the `Query` type | +| `SearchFilter` | `SearchFilter` enum | +| `SearchFilter.OPEN_NOW` | `OPEN_NOW` value of the`SearchFilter` enum | +| `@private` | `@private` directive definition | +| `@private(scope:)` | `scope` argument on the `@private` directive definition | +| `Address` | `Address` interface | +| `Address.city` | `city` field on the `Address` interface | +| `Entity` | `Entity` union definition | -**Selecting an Enum Value** - -Schema Coordinates for the `OPEN_NOW` value of the`SearchFilter` enum: - -```example -SearchFilter.OPEN_NOW -``` - -**Selecting a Directive Definition** - -Schema Coordinates for the `@private` directive definition: - -```example -@private -``` - -**Selecting a Directive Definition Argument** - -Schema Coordinates for the `scope` argument on the `@private` directive definition: - -```example -@private(scope) -``` - -**Selecting an Interface** - -Schema Coordinates for the `Address` interface: - -```example -Address -``` - -**Selecting a Field on an Interface** - -Schema Coordinates for the `city` field on the `Address` interface: - -```example -Address.city -``` - -**Selecting a Union** - -Schema Coordinates for the `Entity` union definition: - -```example -Entity -``` +Note: You may not select members inside a union definition. -You may not select members inside a union definition. +The following counter example are *not* considered valid Schema Coordinates: ```graphql counter-example Entity.Business ``` -In such cases, you may wish to [select the type directly](#sec-Examples.Selecting-a-Type) instead. \ No newline at end of file +In such cases, you may wish to select the type directly instead (e.g. `Business`). \ No newline at end of file From eabdaff30598e3dab34dc48ecaba0dacf583798c Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Sat, 21 Nov 2020 12:12:06 -0800 Subject: [PATCH 03/46] implement PR suggestions - move schema coordinates to section 3.3.3 - add lee's grammar suggestion --- spec/Appendix C -- Schema Coordinates.md | 93 -------------- spec/GraphQL.md | 2 - spec/Section 3 -- Type System.md | 147 +++++++++++++++++++++++ 3 files changed, 147 insertions(+), 95 deletions(-) delete mode 100644 spec/Appendix C -- Schema Coordinates.md diff --git a/spec/Appendix C -- Schema Coordinates.md b/spec/Appendix C -- Schema Coordinates.md deleted file mode 100644 index aea21069e..000000000 --- a/spec/Appendix C -- Schema Coordinates.md +++ /dev/null @@ -1,93 +0,0 @@ -# Appendix: Schema Coordinates - -Schema Coordinates are human readable strings that uniquely identify an element defined in a GraphQL Schema. - -## Definition - -SchemaCoordinates : - - TypeDefinitionName FieldSpecifier? - - EnumName EnumValueSpecifier? - - @ DirectiveName ArgumentSpecifier? - - UnionName - -TypeDefinitionName: - - ObjectTypeName - - InterfaceTypeName - -FieldSpecifier : - - . FieldName ArgumentSpecifier? - -ArgumentSpecifier : - - ( ArgumentName: ) - -EnumValueSpecifier : - - . EnumValue - -## Examples - -This section shows example coordinates for the possible schema element types this syntax covers. - -All examples below will assume the following schema: - -```graphql example -directive @private(scope: String!) on FIELD - -interface Address { - city: String -} - -type User implements Address { - name: String - reviewCount: Int - friends: [User] - email: String @private(scope: 'loggedIn') - city: String -} - -type Business implements Address { - name: String - address: String - rating: Int - city: String -} - -union Entity = User | Business - -enum SearchFilter { - OPEN_NOW - DELIVERS_TAKEOUT - VEGETARIAN_MENU -} - -type Query { - searchBusiness(name: String!, filter: SearchFilter): Business -} -``` - -The following table demonstrates how to select various kinds of schema elements: - -| Example | Description | -| ------------------------------ | ------------------------------------------------------------------- | -| `Business` | `Business` type | -| `User` | `User` type | -| `Business.name` | `name` field on the `Business` type | -| `User.name` | `name` field on the `User` type | -| `Query.searchBusiness(name:)` | `name` argument on the `searchBusiness` field on the `Query` type | -| `Query.searchBusiness(filter:)`| `filter` argument on the `searchBusiness` field on the `Query` type | -| `SearchFilter` | `SearchFilter` enum | -| `SearchFilter.OPEN_NOW` | `OPEN_NOW` value of the`SearchFilter` enum | -| `@private` | `@private` directive definition | -| `@private(scope:)` | `scope` argument on the `@private` directive definition | -| `Address` | `Address` interface | -| `Address.city` | `city` field on the `Address` interface | -| `Entity` | `Entity` union definition | - -Note: You may not select members inside a union definition. - -The following counter example are *not* considered valid Schema Coordinates: - -```graphql counter-example -Entity.Business -``` - -In such cases, you may wish to select the type directly instead (e.g. `Business`). \ No newline at end of file diff --git a/spec/GraphQL.md b/spec/GraphQL.md index aabff200e..fad6bcdbe 100644 --- a/spec/GraphQL.md +++ b/spec/GraphQL.md @@ -139,5 +139,3 @@ Note: This is an example of a non-normative note. # [Appendix: Notation Conventions](Appendix%20A%20--%20Notation%20Conventions.md) # [Appendix: Grammar Summary](Appendix%20B%20--%20Grammar%20Summary.md) - -# [Appendix: Schema Coordinates](Appendix%20C%20--%20Schema%20Coordinates.md) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 1348899fb..1ec512ab5 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -282,6 +282,153 @@ Schema extensions have the potential to be invalid if incorrectly defined. 2. Any non-repeatable directives provided must not already apply to the original Schema. +### Schema Coordinates + +Schema Coordinates are human readable strings that uniquely identify an element defined in a GraphQL Schema. + +**Definition** + +SchemaCoordinate: + - Name + - Name . Name + - Name . Name ( Name : ) + - @ Name + - @ Name ( Name : ) + +**Semantics** + +SchemaCoordinate: Name + 1. Let {typeName} be the value of the first {Name}. + 2. Return the type in the schema named {typeName}. + +SchemaCoordinate: Name . Name + 1. Let {typeName} be the value of the first {Name}. + 2. Let {type} be the type in the schema named {typeName}. + 3. If {type} is an Enum type: + 1. Let {enumName} be the value of the second {Name}. + 2. Return the enum value of {type} named {enumName}. + 4. Otherwise if {type} is an Input Object type: + 1. Let {inputFieldName} be the value of the second {Name}. + 2. Return the input field of {type} named {inputFieldName}. + 5. Otherwise {type} must be an Object or Interface type: + 1. Let {fieldName} be the value of the second {Name}. + 2. Return the field of {type} named {fieldName}. + +SchemaCoordinate: Name . Name ( Name : ) + 1. Let {typeName} be the value of the first {Name}. + 2. Let {type} be the type in the schema named {typeName}. + 3. Assert: {type} must be an Object or Interface type. + 4. Let {fieldName} be the value of the second {Name}. + 5. Let {field} be the field of {type} named {fieldName}. + 6. Assert: {field} must exist. + 7. Let {argumentName} be the value of the third {Name}. + 8. Return the argument of {field} named {argumentName}. + +SchemaCoordinate: @ Name + 1. Let {directiveName} be the value of the first {Name}. + 2. Return the directive in the schema named {directiveName}. + +SchemaCoordinate: @ Name ( Name : ) + 1. Let {directiveName} be the value of the first {Name}. + 2. Let {directive} be the directive in the schema named {directiveName}. + 3. Assert: {directive} must exist. + 7. Let {argumentName} be the value of the second {Name}. + 8. Return the argument of {directive} named {argumentName} + +**Examples** + +This section shows example coordinates for the possible schema element types this syntax covers. + +All examples below will assume the following schema: + +```graphql example +directive @private(scope: String!) on FIELD + +scalar DateTime + +input ReviewInput { + content: String + author: String + businessId: String +} + +interface Address { + city: String +} + +type User implements Address { + name: String + reviewCount: Int + friends: [User] + email: String @private(scope: "loggedIn") + city: String +} + +type Business implements Address { + name: String + address: String + rating: Int + city: String + reviews: [Review] + createdAt: DateTime +} + +type Review { + content: String + author: User + business: Business + createdAt: DateTime +} + +union Entity = User | Business | Review + +enum SearchFilter { + OPEN_NOW + DELIVERS_TAKEOUT + VEGETARIAN_MENU +} + +type Query { + searchBusiness(name: String!, filter: SearchFilter): Business +} + +type Mutation { + addReview(input: ReviewInput!): Review +} +``` + +The following table demonstrates how to select various kinds of schema elements: + +| Example | Description | +| ------------------------------ | ------------------------------------------------------------------- | +| `Business` | `Business` type | +| `User` | `User` type | +| `Business.name` | `name` field on the `Business` type | +| `User.name` | `name` field on the `User` type | +| `Query.searchBusiness(name:)` | `name` argument on the `searchBusiness` field on the `Query` type | +| `Query.searchBusiness(filter:)`| `filter` argument on the `searchBusiness` field on the `Query` type | +| `SearchFilter` | `SearchFilter` enum | +| `SearchFilter.OPEN_NOW` | `OPEN_NOW` value of the`SearchFilter` enum | +| `@private` | `@private` directive definition | +| `@private(scope:)` | `scope` argument on the `@private` directive definition | +| `Address` | `Address` interface | +| `Address.city` | `city` field on the `Address` interface | +| `ReviewInput` | `ReviewInput` input object type | +| `ReviewInput.author` | `author` field on the `ReviewInput` input object type | +| `Entity` | `Entity` union definition | +| `DateTime` | Custom `DateTime` scalar type | +| `String` | Built-in `String` scalar type | + +Note: You may not select members inside a union definition. + +The following counter example is *not* considered a valid Schema Coordinate: + +```graphql counter-example +Entity.Business +``` + +In such cases, you may wish to select the type directly instead (e.g. `Business`). + ## Types TypeDefinition : From f994f99c714a5d7975872b8ee158d1e9b3be4e7e Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Sun, 22 Nov 2020 11:43:45 -0800 Subject: [PATCH 04/46] Tweak example table wording --- spec/Section 3 -- Type System.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 1ec512ab5..d6381fad9 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -397,9 +397,9 @@ type Mutation { } ``` -The following table demonstrates how to select various kinds of schema elements: +The following table demonstrates how to select various kinds of schema members: -| Example | Description | +| Schema Coordinate | Description | | ------------------------------ | ------------------------------------------------------------------- | | `Business` | `Business` type | | `User` | `User` type | From 17002d489121b8a59a0ba8fb5576f27005aebe66 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Mon, 23 Nov 2020 12:47:27 -0800 Subject: [PATCH 05/46] Apply suggestions from code review Co-authored-by: Benjie Gillam --- spec/Section 3 -- Type System.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index d6381fad9..a3c6b61b1 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -310,9 +310,10 @@ SchemaCoordinate: Name . Name 4. Otherwise if {type} is an Input Object type: 1. Let {inputFieldName} be the value of the second {Name}. 2. Return the input field of {type} named {inputFieldName}. - 5. Otherwise {type} must be an Object or Interface type: - 1. Let {fieldName} be the value of the second {Name}. - 2. Return the field of {type} named {fieldName}. + 5. Otherwise: + 1. Assert: {type} must be an Object or Interface type. + 2. Let {fieldName} be the value of the second {Name}. + 3. Return the field of {type} named {fieldName}. SchemaCoordinate: Name . Name ( Name : ) 1. Let {typeName} be the value of the first {Name}. @@ -414,7 +415,7 @@ The following table demonstrates how to select various kinds of schema members: | `Address` | `Address` interface | | `Address.city` | `city` field on the `Address` interface | | `ReviewInput` | `ReviewInput` input object type | -| `ReviewInput.author` | `author` field on the `ReviewInput` input object type | +| `ReviewInput.author` | `author` input field on the `ReviewInput` input object type | | `Entity` | `Entity` union definition | | `DateTime` | Custom `DateTime` scalar type | | `String` | Built-in `String` scalar type | From 6456c5f432225b446d685911272c7ea490d72ab6 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Sat, 28 Nov 2020 00:20:57 -0800 Subject: [PATCH 06/46] enumName -> enumValueName --- spec/Section 3 -- Type System.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index a3c6b61b1..1e001033f 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -305,8 +305,8 @@ SchemaCoordinate: Name . Name 1. Let {typeName} be the value of the first {Name}. 2. Let {type} be the type in the schema named {typeName}. 3. If {type} is an Enum type: - 1. Let {enumName} be the value of the second {Name}. - 2. Return the enum value of {type} named {enumName}. + 1. Let {enumValueName} be the value of the second {Name}. + 2. Return the enum value of {type} named {enumValueName}. 4. Otherwise if {type} is an Input Object type: 1. Let {inputFieldName} be the value of the second {Name}. 2. Return the input field of {type} named {inputFieldName}. From 49059778dedf8d2f278c50d5885a7edb9e679852 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Mon, 4 Jan 2021 00:11:51 -0800 Subject: [PATCH 07/46] - Add PR feedback - remove extraneous examples - tighten up wording --- spec/Section 3 -- Type System.md | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 1e001033f..868d01be2 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -284,7 +284,8 @@ Schema extensions have the potential to be invalid if incorrectly defined. ### Schema Coordinates -Schema Coordinates are human readable strings that uniquely identify an element defined in a GraphQL Schema. +Schema Coordinates are human readable strings that uniquely identify a specific +type, field, argument, enum value, or directive defined in a GraphQL Schema. **Definition** @@ -295,6 +296,12 @@ SchemaCoordinate: - @ Name - @ Name ( Name : ) +Note: The `SchemaCoordinate` syntax is not part of a GraphQL Document. Schema +Coordinates are a separate syntax, intended to be used by tooling when +referencing types and fields or other schema elements. (For example, a server +that wishes to keep track of the number of times fields have been accessed may +use their Schema Coordinate as the lookup key.) + **Semantics** SchemaCoordinate: Name @@ -338,7 +345,8 @@ SchemaCoordinate: @ Name ( Name : ) **Examples** -This section shows example coordinates for the possible schema element types this syntax covers. +This section shows example coordinates for the possible schema element types +this syntax covers. All examples below will assume the following schema: @@ -398,16 +406,14 @@ type Mutation { } ``` -The following table demonstrates how to select various kinds of schema members: +The following table shows examples of Schema Coordinates for elements in the +schema above: | Schema Coordinate | Description | | ------------------------------ | ------------------------------------------------------------------- | | `Business` | `Business` type | -| `User` | `User` type | -| `Business.name` | `name` field on the `Business` type | | `User.name` | `name` field on the `User` type | | `Query.searchBusiness(name:)` | `name` argument on the `searchBusiness` field on the `Query` type | -| `Query.searchBusiness(filter:)`| `filter` argument on the `searchBusiness` field on the `Query` type | | `SearchFilter` | `SearchFilter` enum | | `SearchFilter.OPEN_NOW` | `OPEN_NOW` value of the`SearchFilter` enum | | `@private` | `@private` directive definition | @@ -420,15 +426,19 @@ The following table demonstrates how to select various kinds of schema members: | `DateTime` | Custom `DateTime` scalar type | | `String` | Built-in `String` scalar type | -Note: You may not select members inside a union definition. +Schema Coordinates are always unique. Each type, field, argument, enum value, or +directive may be referenced by exactly one possible Schema Coordinate. -The following counter example is *not* considered a valid Schema Coordinate: +For example, the following is *not* a valid Schema Coordinate: ```graphql counter-example Entity.Business ``` -In such cases, you may wish to select the type directly instead (e.g. `Business`). +In this counter example, both `Entity.Business` and `Business` would refer to +the `Business` type. Since it would be ambiguous what the "primary key" should +be in an application that uses Schema Coordinates to reference types, this is +not allowed. ## Types From 8be29ca0253d0453633b48429884320d6d8cf131 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Thu, 7 Jan 2021 11:11:46 -0800 Subject: [PATCH 08/46] Update Section 3 -- Type System.md --- spec/Section 3 -- Type System.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 868d01be2..a035381e6 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -435,10 +435,10 @@ For example, the following is *not* a valid Schema Coordinate: Entity.Business ``` -In this counter example, both `Entity.Business` and `Business` would refer to -the `Business` type. Since it would be ambiguous what the "primary key" should -be in an application that uses Schema Coordinates to reference types, this is -not allowed. +In this counter example, `Entity.Business` is redundant since `Business` already +uniquely identifies the Business type. Such redundancy is disallowed by this +spec - every type, field, field argument, enum value, directive, and directive +argument has exactly one canonical Schema Coordinate. ## Types From 568d26f4ed13c9d01b585a2fb97f6223fe1d89d8 Mon Sep 17 00:00:00 2001 From: Lee Byron Date: Tue, 13 Apr 2021 14:34:26 -0700 Subject: [PATCH 09/46] Editorial on grammar and semantics --- spec/Appendix B -- Grammar Summary.md | 7 ++++ spec/Section 3 -- Type System.md | 48 +++++++++++++-------------- 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/spec/Appendix B -- Grammar Summary.md b/spec/Appendix B -- Grammar Summary.md index 92f222cb3..11ceaecab 100644 --- a/spec/Appendix B -- Grammar Summary.md +++ b/spec/Appendix B -- Grammar Summary.md @@ -268,6 +268,13 @@ SchemaExtension : RootOperationTypeDefinition : OperationType : NamedType +SchemaCoordinate : + - Name + - Name . Name + - Name . Name ( Name : ) + - @ Name + - @ Name ( Name : ) + Description : StringValue TypeDefinition : diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index a035381e6..745f9815f 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -287,30 +287,30 @@ Schema extensions have the potential to be invalid if incorrectly defined. Schema Coordinates are human readable strings that uniquely identify a specific type, field, argument, enum value, or directive defined in a GraphQL Schema. -**Definition** - -SchemaCoordinate: +SchemaCoordinate : - Name - Name . Name - Name . Name ( Name : ) - @ Name - @ Name ( Name : ) -Note: The `SchemaCoordinate` syntax is not part of a GraphQL Document. Schema -Coordinates are a separate syntax, intended to be used by tooling when -referencing types and fields or other schema elements. (For example, a server -that wishes to keep track of the number of times fields have been accessed may -use their Schema Coordinate as the lookup key.) +Note: A {SchemaCoordinate} is not a definition within a GraphQL {Document}. +Schema coordinates are a separate syntax, intended to be used by tools to +reference types and fields or other schema elements. For example: within +documentation, or as lookup keys a service uses to track usage frequency. **Semantics** -SchemaCoordinate: Name +A schema coordinate's semantics assume they are interpreted in the context of +a single GraphQL {schema}. + +SchemaCoordinate : Name 1. Let {typeName} be the value of the first {Name}. - 2. Return the type in the schema named {typeName}. + 2. Return the type in the {schema} named {typeName}. -SchemaCoordinate: Name . Name +SchemaCoordinate : Name . Name 1. Let {typeName} be the value of the first {Name}. - 2. Let {type} be the type in the schema named {typeName}. + 2. Let {type} be the type in the {schema} named {typeName}. 3. If {type} is an Enum type: 1. Let {enumValueName} be the value of the second {Name}. 2. Return the enum value of {type} named {enumValueName}. @@ -318,30 +318,30 @@ SchemaCoordinate: Name . Name 1. Let {inputFieldName} be the value of the second {Name}. 2. Return the input field of {type} named {inputFieldName}. 5. Otherwise: - 1. Assert: {type} must be an Object or Interface type. + 1. Assert {type} must be an Object or Interface type. 2. Let {fieldName} be the value of the second {Name}. 3. Return the field of {type} named {fieldName}. - -SchemaCoordinate: Name . Name ( Name : ) + +SchemaCoordinate : Name . Name ( Name : ) 1. Let {typeName} be the value of the first {Name}. - 2. Let {type} be the type in the schema named {typeName}. - 3. Assert: {type} must be an Object or Interface type. + 2. Let {type} be the type in the {schema} named {typeName}. + 3. Assert {type} must be an Object or Interface type. 4. Let {fieldName} be the value of the second {Name}. 5. Let {field} be the field of {type} named {fieldName}. - 6. Assert: {field} must exist. + 6. Assert {field} must exist. 7. Let {argumentName} be the value of the third {Name}. 8. Return the argument of {field} named {argumentName}. -SchemaCoordinate: @ Name +SchemaCoordinate : @ Name 1. Let {directiveName} be the value of the first {Name}. - 2. Return the directive in the schema named {directiveName}. + 2. Return the directive in the {schema} named {directiveName}. -SchemaCoordinate: @ Name ( Name : ) +SchemaCoordinate : @ Name ( Name : ) 1. Let {directiveName} be the value of the first {Name}. - 2. Let {directive} be the directive in the schema named {directiveName}. - 3. Assert: {directive} must exist. + 2. Let {directive} be the directive in the {schema} named {directiveName}. + 3. Assert {directive} must exist. 7. Let {argumentName} be the value of the second {Name}. - 8. Return the argument of {directive} named {argumentName} + 8. Return the argument of {directive} named {argumentName}. **Examples** From b8f3f4709cf48356ab3ab12b81be8781baba6121 Mon Sep 17 00:00:00 2001 From: Lee Byron Date: Tue, 13 Apr 2021 16:52:38 -0700 Subject: [PATCH 10/46] Move section --- spec/Appendix B -- Grammar Summary.md | 14 +- spec/Section 3 -- Type System.md | 315 +++++++++++++------------- 2 files changed, 165 insertions(+), 164 deletions(-) diff --git a/spec/Appendix B -- Grammar Summary.md b/spec/Appendix B -- Grammar Summary.md index 11ceaecab..e42bd7953 100644 --- a/spec/Appendix B -- Grammar Summary.md +++ b/spec/Appendix B -- Grammar Summary.md @@ -268,13 +268,6 @@ SchemaExtension : RootOperationTypeDefinition : OperationType : NamedType -SchemaCoordinate : - - Name - - Name . Name - - Name . Name ( Name : ) - - @ Name - - @ Name ( Name : ) - Description : StringValue TypeDefinition : @@ -419,3 +412,10 @@ TypeSystemDirectiveLocation : one of - `ENUM_VALUE` - `INPUT_OBJECT` - `INPUT_FIELD_DEFINITION` + +SchemaCoordinate : +- Name +- Name . Name +- Name . Name ( Name : ) +- @ Name +- @ Name ( Name : ) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 745f9815f..77e482b3f 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -282,163 +282,6 @@ Schema extensions have the potential to be invalid if incorrectly defined. 2. Any non-repeatable directives provided must not already apply to the original Schema. -### Schema Coordinates - -Schema Coordinates are human readable strings that uniquely identify a specific -type, field, argument, enum value, or directive defined in a GraphQL Schema. - -SchemaCoordinate : - - Name - - Name . Name - - Name . Name ( Name : ) - - @ Name - - @ Name ( Name : ) - -Note: A {SchemaCoordinate} is not a definition within a GraphQL {Document}. -Schema coordinates are a separate syntax, intended to be used by tools to -reference types and fields or other schema elements. For example: within -documentation, or as lookup keys a service uses to track usage frequency. - -**Semantics** - -A schema coordinate's semantics assume they are interpreted in the context of -a single GraphQL {schema}. - -SchemaCoordinate : Name - 1. Let {typeName} be the value of the first {Name}. - 2. Return the type in the {schema} named {typeName}. - -SchemaCoordinate : Name . Name - 1. Let {typeName} be the value of the first {Name}. - 2. Let {type} be the type in the {schema} named {typeName}. - 3. If {type} is an Enum type: - 1. Let {enumValueName} be the value of the second {Name}. - 2. Return the enum value of {type} named {enumValueName}. - 4. Otherwise if {type} is an Input Object type: - 1. Let {inputFieldName} be the value of the second {Name}. - 2. Return the input field of {type} named {inputFieldName}. - 5. Otherwise: - 1. Assert {type} must be an Object or Interface type. - 2. Let {fieldName} be the value of the second {Name}. - 3. Return the field of {type} named {fieldName}. - -SchemaCoordinate : Name . Name ( Name : ) - 1. Let {typeName} be the value of the first {Name}. - 2. Let {type} be the type in the {schema} named {typeName}. - 3. Assert {type} must be an Object or Interface type. - 4. Let {fieldName} be the value of the second {Name}. - 5. Let {field} be the field of {type} named {fieldName}. - 6. Assert {field} must exist. - 7. Let {argumentName} be the value of the third {Name}. - 8. Return the argument of {field} named {argumentName}. - -SchemaCoordinate : @ Name - 1. Let {directiveName} be the value of the first {Name}. - 2. Return the directive in the {schema} named {directiveName}. - -SchemaCoordinate : @ Name ( Name : ) - 1. Let {directiveName} be the value of the first {Name}. - 2. Let {directive} be the directive in the {schema} named {directiveName}. - 3. Assert {directive} must exist. - 7. Let {argumentName} be the value of the second {Name}. - 8. Return the argument of {directive} named {argumentName}. - -**Examples** - -This section shows example coordinates for the possible schema element types -this syntax covers. - -All examples below will assume the following schema: - -```graphql example -directive @private(scope: String!) on FIELD - -scalar DateTime - -input ReviewInput { - content: String - author: String - businessId: String -} - -interface Address { - city: String -} - -type User implements Address { - name: String - reviewCount: Int - friends: [User] - email: String @private(scope: "loggedIn") - city: String -} - -type Business implements Address { - name: String - address: String - rating: Int - city: String - reviews: [Review] - createdAt: DateTime -} - -type Review { - content: String - author: User - business: Business - createdAt: DateTime -} - -union Entity = User | Business | Review - -enum SearchFilter { - OPEN_NOW - DELIVERS_TAKEOUT - VEGETARIAN_MENU -} - -type Query { - searchBusiness(name: String!, filter: SearchFilter): Business -} - -type Mutation { - addReview(input: ReviewInput!): Review -} -``` - -The following table shows examples of Schema Coordinates for elements in the -schema above: - -| Schema Coordinate | Description | -| ------------------------------ | ------------------------------------------------------------------- | -| `Business` | `Business` type | -| `User.name` | `name` field on the `User` type | -| `Query.searchBusiness(name:)` | `name` argument on the `searchBusiness` field on the `Query` type | -| `SearchFilter` | `SearchFilter` enum | -| `SearchFilter.OPEN_NOW` | `OPEN_NOW` value of the`SearchFilter` enum | -| `@private` | `@private` directive definition | -| `@private(scope:)` | `scope` argument on the `@private` directive definition | -| `Address` | `Address` interface | -| `Address.city` | `city` field on the `Address` interface | -| `ReviewInput` | `ReviewInput` input object type | -| `ReviewInput.author` | `author` input field on the `ReviewInput` input object type | -| `Entity` | `Entity` union definition | -| `DateTime` | Custom `DateTime` scalar type | -| `String` | Built-in `String` scalar type | - -Schema Coordinates are always unique. Each type, field, argument, enum value, or -directive may be referenced by exactly one possible Schema Coordinate. - -For example, the following is *not* a valid Schema Coordinate: - -```graphql counter-example -Entity.Business -``` - -In this counter example, `Entity.Business` is redundant since `Business` already -uniquely identifies the Business type. Such redundancy is disallowed by this -spec - every type, field, field argument, enum value, directive, and directive -argument has exactly one canonical Schema Coordinate. ## Types @@ -2322,3 +2165,161 @@ to the relevant IETF specification. ```graphql example scalar UUID @specifiedBy(url: "https://tools.ietf.org/html/rfc4122") ``` + +## Schema Coordinates + +Schema Coordinates are human readable strings that uniquely identify a specific +type, field, argument, enum value, or directive defined in a GraphQL Schema. + +SchemaCoordinate : + - Name + - Name . Name + - Name . Name ( Name : ) + - @ Name + - @ Name ( Name : ) + +Note: A {SchemaCoordinate} is not a definition within a GraphQL {Document}. +Schema coordinates are a separate syntax, intended to be used by tools to +reference types and fields or other schema elements. For example: within +documentation, or as lookup keys a service uses to track usage frequency. + +**Semantics** + +A schema coordinate's semantics assume they are interpreted in the context of +a single GraphQL {schema}. + +SchemaCoordinate : Name + 1. Let {typeName} be the value of the first {Name}. + 2. Return the type in the {schema} named {typeName}. + +SchemaCoordinate : Name . Name + 1. Let {typeName} be the value of the first {Name}. + 2. Let {type} be the type in the {schema} named {typeName}. + 3. If {type} is an Enum type: + 1. Let {enumValueName} be the value of the second {Name}. + 2. Return the enum value of {type} named {enumValueName}. + 4. Otherwise if {type} is an Input Object type: + 1. Let {inputFieldName} be the value of the second {Name}. + 2. Return the input field of {type} named {inputFieldName}. + 5. Otherwise: + 1. Assert {type} must be an Object or Interface type. + 2. Let {fieldName} be the value of the second {Name}. + 3. Return the field of {type} named {fieldName}. + +SchemaCoordinate : Name . Name ( Name : ) + 1. Let {typeName} be the value of the first {Name}. + 2. Let {type} be the type in the {schema} named {typeName}. + 3. Assert {type} must be an Object or Interface type. + 4. Let {fieldName} be the value of the second {Name}. + 5. Let {field} be the field of {type} named {fieldName}. + 6. Assert {field} must exist. + 7. Let {argumentName} be the value of the third {Name}. + 8. Return the argument of {field} named {argumentName}. + +SchemaCoordinate : @ Name + 1. Let {directiveName} be the value of the first {Name}. + 2. Return the directive in the {schema} named {directiveName}. + +SchemaCoordinate : @ Name ( Name : ) + 1. Let {directiveName} be the value of the first {Name}. + 2. Let {directive} be the directive in the {schema} named {directiveName}. + 3. Assert {directive} must exist. + 7. Let {argumentName} be the value of the second {Name}. + 8. Return the argument of {directive} named {argumentName}. + +**Examples** + +This section shows example coordinates for the possible schema element types +this syntax covers. + +All examples below will assume the following schema: + +```graphql example +directive @private(scope: String!) on FIELD + +scalar DateTime + +input ReviewInput { + content: String + author: String + businessId: String +} + +interface Address { + city: String +} + +type User implements Address { + name: String + reviewCount: Int + friends: [User] + email: String @private(scope: "loggedIn") + city: String +} + +type Business implements Address { + name: String + address: String + rating: Int + city: String + reviews: [Review] + createdAt: DateTime +} + +type Review { + content: String + author: User + business: Business + createdAt: DateTime +} + +union Entity = User | Business | Review + +enum SearchFilter { + OPEN_NOW + DELIVERS_TAKEOUT + VEGETARIAN_MENU +} + +type Query { + searchBusiness(name: String!, filter: SearchFilter): Business +} + +type Mutation { + addReview(input: ReviewInput!): Review +} +``` + +The following table shows examples of Schema Coordinates for elements in the +schema above: + +| Schema Coordinate | Description | +| ------------------------------ | ------------------------------------------------------------------- | +| `Business` | `Business` type | +| `User.name` | `name` field on the `User` type | +| `Query.searchBusiness(name:)` | `name` argument on the `searchBusiness` field on the `Query` type | +| `SearchFilter` | `SearchFilter` enum | +| `SearchFilter.OPEN_NOW` | `OPEN_NOW` value of the`SearchFilter` enum | +| `@private` | `@private` directive definition | +| `@private(scope:)` | `scope` argument on the `@private` directive definition | +| `Address` | `Address` interface | +| `Address.city` | `city` field on the `Address` interface | +| `ReviewInput` | `ReviewInput` input object type | +| `ReviewInput.author` | `author` input field on the `ReviewInput` input object type | +| `Entity` | `Entity` union definition | +| `DateTime` | Custom `DateTime` scalar type | +| `String` | Built-in `String` scalar type | + +Schema Coordinates are always unique. Each type, field, argument, enum value, or +directive may be referenced by exactly one possible Schema Coordinate. + +For example, the following is *not* a valid Schema Coordinate: + +```graphql counter-example +Entity.Business +``` + +In this counter example, `Entity.Business` is redundant since `Business` already +uniquely identifies the Business type. Such redundancy is disallowed by this +spec - every type, field, field argument, enum value, directive, and directive +argument has exactly one canonical Schema Coordinate. From 85801629d9c2b7a2c6983f74f6afefc268efbdca Mon Sep 17 00:00:00 2001 From: Lee Byron Date: Tue, 13 Apr 2021 17:59:55 -0700 Subject: [PATCH 11/46] Simplify examples --- spec/Section 3 -- Type System.md | 135 ++++++++++--------------------- 1 file changed, 44 insertions(+), 91 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 77e482b3f..8e2b5e08e 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2168,9 +2168,6 @@ scalar UUID @specifiedBy(url: "https://tools.ietf.org/html/rfc4122") ## Schema Coordinates -Schema Coordinates are human readable strings that uniquely identify a specific -type, field, argument, enum value, or directive defined in a GraphQL Schema. - SchemaCoordinate : - Name - Name . Name @@ -2178,15 +2175,28 @@ SchemaCoordinate : - @ Name - @ Name ( Name : ) -Note: A {SchemaCoordinate} is not a definition within a GraphQL {Document}. -Schema coordinates are a separate syntax, intended to be used by tools to -reference types and fields or other schema elements. For example: within -documentation, or as lookup keys a service uses to track usage frequency. +:: A *schema coordinate* is a human readable string that uniquely identifies a +*schema element* within a GraphQL Schema. + +:: A *schema element* is a specific instance of a named type, type field, +input field, enum value, field argument, directive, or directive argument. + +A *schema coordinate* is always unique. Each *schema element* may be referenced +by exactly one possible schema coordinate. + +A *schema coordinate* may refer to either a defined or built-in *schema element*. +For example, `String` and `@deprecated(reason:)` are both valid schema +coordinates which refer to built-in schema elements. + +Note: A {SchemaCoordinate} is not a definition within a GraphQL {Document}, but +a separate stand-alone grammar, intended to be used by tools to reference types, +fields, and other *schema element*s. For example as references within +documentation, or as lookup keys in usage frequency tracking. **Semantics** -A schema coordinate's semantics assume they are interpreted in the context of -a single GraphQL {schema}. +To refer to a *schema element*, a *schema coordinate* must be interpreted in the +context of a GraphQL {schema}. SchemaCoordinate : Name 1. Let {typeName} be the value of the first {Name}. @@ -2229,97 +2239,40 @@ SchemaCoordinate : @ Name ( Name : ) **Examples** -This section shows example coordinates for the possible schema element types -this syntax covers. +| Element Kind | *Schema Coordinate* | *Schema Element* | +| ------------------ | -------------------------------- | ----------------------------------------------------------------------- | +| Named Type | `Business` | `Business` type | +| Type Field | `Business.name` | `name` field on the `Business` type | +| Input Field | `SearchCriteria.filter` | `filter` input field on the `SearchCriteria` input object type | +| Enum Value | `SearchFilter.OPEN_NOW` | `OPEN_NOW` value of the `SearchFilter` enum | +| Field Argument | `Query.searchBusiness(criteria:)`| `criteria` argument on the `searchBusiness` field on the `Query` type | +| Directive | `@private` | `@private` directive | +| Directive Argument | `@private(scope:)` | `scope` argument on the `@private` directive | -All examples below will assume the following schema: +The table above shows an example of a *schema coordinate* for every kind of +*schema element* based on the schema below. -```graphql example -directive @private(scope: String!) on FIELD - -scalar DateTime - -input ReviewInput { - content: String - author: String - businessId: String -} - -interface Address { - city: String -} - -type User implements Address { - name: String - reviewCount: Int - friends: [User] - email: String @private(scope: "loggedIn") - city: String -} - -type Business implements Address { - name: String - address: String - rating: Int - city: String - reviews: [Review] - createdAt: DateTime +```graphql +type Query { + searchBusiness(criteria: SearchCriteria!): [Business] } -type Review { - content: String - author: User - business: Business - createdAt: DateTime +input SearchCriteria { + name: String + filter: SearchFilter } -union Entity = User | Business | Review - enum SearchFilter { - OPEN_NOW - DELIVERS_TAKEOUT - VEGETARIAN_MENU -} - -type Query { - searchBusiness(name: String!, filter: SearchFilter): Business + OPEN_NOW + DELIVERS_TAKEOUT + VEGETARIAN_MENU } -type Mutation { - addReview(input: ReviewInput!): Review +type Business { + id: ID + name: String + email: String @private(scope: "loggedIn") } -``` - -The following table shows examples of Schema Coordinates for elements in the -schema above: - -| Schema Coordinate | Description | -| ------------------------------ | ------------------------------------------------------------------- | -| `Business` | `Business` type | -| `User.name` | `name` field on the `User` type | -| `Query.searchBusiness(name:)` | `name` argument on the `searchBusiness` field on the `Query` type | -| `SearchFilter` | `SearchFilter` enum | -| `SearchFilter.OPEN_NOW` | `OPEN_NOW` value of the`SearchFilter` enum | -| `@private` | `@private` directive definition | -| `@private(scope:)` | `scope` argument on the `@private` directive definition | -| `Address` | `Address` interface | -| `Address.city` | `city` field on the `Address` interface | -| `ReviewInput` | `ReviewInput` input object type | -| `ReviewInput.author` | `author` input field on the `ReviewInput` input object type | -| `Entity` | `Entity` union definition | -| `DateTime` | Custom `DateTime` scalar type | -| `String` | Built-in `String` scalar type | - -Schema Coordinates are always unique. Each type, field, argument, enum value, or -directive may be referenced by exactly one possible Schema Coordinate. -For example, the following is *not* a valid Schema Coordinate: - -```graphql counter-example -Entity.Business +directive @private(scope: String!) on FIELD ``` - -In this counter example, `Entity.Business` is redundant since `Business` already -uniquely identifies the Business type. Such redundancy is disallowed by this -spec - every type, field, field argument, enum value, directive, and directive -argument has exactly one canonical Schema Coordinate. From 87a38e2addb7bda9b5c93ee3a1c0dbd2f53a3dd3 Mon Sep 17 00:00:00 2001 From: Lee Byron Date: Thu, 15 Apr 2021 10:17:01 -0700 Subject: [PATCH 12/46] standalone https://brians.wsu.edu/2016/05/31/standalone-stand-alone/ Co-authored-by: Benjie Gillam --- spec/Appendix B -- Grammar Summary.md | 2 +- spec/Section 2 -- Language.md | 2 +- spec/Section 3 -- Type System.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/Appendix B -- Grammar Summary.md b/spec/Appendix B -- Grammar Summary.md index e42bd7953..6d4688536 100644 --- a/spec/Appendix B -- Grammar Summary.md +++ b/spec/Appendix B -- Grammar Summary.md @@ -43,7 +43,7 @@ Token :: - FloatValue - StringValue -Punctuator :: one of ! $ & ( ) ... : = @ [ ] { | } +Punctuator :: one of ! $ & ( ) ... : = @ [ ] { | } . [lookahead != .] Name :: diff --git a/spec/Section 2 -- Language.md b/spec/Section 2 -- Language.md index 76b5fadcb..d981abbe1 100644 --- a/spec/Section 2 -- Language.md +++ b/spec/Section 2 -- Language.md @@ -176,7 +176,7 @@ and is {Ignored}. ### Punctuators -Punctuator :: one of ! $ & ( ) ... : = @ [ ] { | } +Punctuator :: one of ! $ & ( ) ... : = @ [ ] { | } . [lookahead != .] GraphQL documents include punctuation in order to describe structure. GraphQL is a data description language and not a programming language, therefore GraphQL diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 8e2b5e08e..41b377513 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2189,7 +2189,7 @@ For example, `String` and `@deprecated(reason:)` are both valid schema coordinates which refer to built-in schema elements. Note: A {SchemaCoordinate} is not a definition within a GraphQL {Document}, but -a separate stand-alone grammar, intended to be used by tools to reference types, +a separate standalone grammar, intended to be used by tools to reference types, fields, and other *schema element*s. For example as references within documentation, or as lookup keys in usage frequency tracking. From 75c48ba25f4a665ec390829bcbd4c861dd063ce9 Mon Sep 17 00:00:00 2001 From: Lee Byron Date: Thu, 15 Apr 2021 23:07:26 -0700 Subject: [PATCH 13/46] update numbers --- spec/Section 3 -- Type System.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 41b377513..2cb1bc3d2 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2234,8 +2234,8 @@ SchemaCoordinate : @ Name ( Name : ) 1. Let {directiveName} be the value of the first {Name}. 2. Let {directive} be the directive in the {schema} named {directiveName}. 3. Assert {directive} must exist. - 7. Let {argumentName} be the value of the second {Name}. - 8. Return the argument of {directive} named {argumentName}. + 4. Let {argumentName} be the value of the second {Name}. + 5. Return the argument of {directive} named {argumentName}. **Examples** From 148d073afa7de9a0e766f6f1cd9fb87e8e43cd9f Mon Sep 17 00:00:00 2001 From: Lee Byron Date: Thu, 15 Apr 2021 23:22:43 -0700 Subject: [PATCH 14/46] clarify element --- spec/Section 3 -- Type System.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 2cb1bc3d2..016ab6f4c 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2179,7 +2179,7 @@ SchemaCoordinate : *schema element* within a GraphQL Schema. :: A *schema element* is a specific instance of a named type, type field, -input field, enum value, field argument, directive, or directive argument. +input field, enum value, argument, or directive. A *schema coordinate* is always unique. Each *schema element* may be referenced by exactly one possible schema coordinate. From c43f4aacabc51ec18b5053546c5d2101157fcc0a Mon Sep 17 00:00:00 2001 From: Lee Byron Date: Fri, 16 Apr 2021 00:13:03 -0700 Subject: [PATCH 15/46] Update Punctuator grammar --- spec/Appendix B -- Grammar Summary.md | 2 +- spec/Section 2 -- Language.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/Appendix B -- Grammar Summary.md b/spec/Appendix B -- Grammar Summary.md index 6d4688536..f9372bb9e 100644 --- a/spec/Appendix B -- Grammar Summary.md +++ b/spec/Appendix B -- Grammar Summary.md @@ -43,7 +43,7 @@ Token :: - FloatValue - StringValue -Punctuator :: one of ! $ & ( ) ... : = @ [ ] { | } . [lookahead != .] +Punctuator :: one of ! $ & ( ) ... : = @ [ ] { | } . [lookahead != {`.`, Digit}] Name :: diff --git a/spec/Section 2 -- Language.md b/spec/Section 2 -- Language.md index d981abbe1..d64237e0d 100644 --- a/spec/Section 2 -- Language.md +++ b/spec/Section 2 -- Language.md @@ -176,7 +176,7 @@ and is {Ignored}. ### Punctuators -Punctuator :: one of ! $ & ( ) ... : = @ [ ] { | } . [lookahead != .] +Punctuator :: one of ! $ & ( ) ... : = @ [ ] { | } . [lookahead != {`.`, Digit}] GraphQL documents include punctuation in order to describe structure. GraphQL is a data description language and not a programming language, therefore GraphQL From bb896cf2fbc01e80266db158985fa0cb7a291d46 Mon Sep 17 00:00:00 2001 From: Lee Byron Date: Fri, 16 Apr 2021 00:36:55 -0700 Subject: [PATCH 16/46] specify schema element --- spec/Section 3 -- Type System.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 016ab6f4c..2cb1bc3d2 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2179,7 +2179,7 @@ SchemaCoordinate : *schema element* within a GraphQL Schema. :: A *schema element* is a specific instance of a named type, type field, -input field, enum value, argument, or directive. +input field, enum value, field argument, directive, or directive argument. A *schema coordinate* is always unique. Each *schema element* may be referenced by exactly one possible schema coordinate. From e5a20921765755ba76069f9cfd19cbf016cd94ab Mon Sep 17 00:00:00 2001 From: Lee Byron Date: Fri, 16 Apr 2021 01:43:32 -0700 Subject: [PATCH 17/46] fix example --- spec/Section 3 -- Type System.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 2cb1bc3d2..32730cbc2 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2274,5 +2274,5 @@ type Business { email: String @private(scope: "loggedIn") } -directive @private(scope: String!) on FIELD +directive @private(scope: String!) on FIELD_DEFINITION ``` From b65eb313af7a844d243473743881412cad049014 Mon Sep 17 00:00:00 2001 From: Lee Byron Date: Fri, 16 Apr 2021 01:57:34 -0700 Subject: [PATCH 18/46] clarify metafields --- spec/Section 3 -- Type System.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 32730cbc2..d70efe1db 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2186,7 +2186,9 @@ by exactly one possible schema coordinate. A *schema coordinate* may refer to either a defined or built-in *schema element*. For example, `String` and `@deprecated(reason:)` are both valid schema -coordinates which refer to built-in schema elements. +coordinates which refer to built-in schema elements. However it must not refer +to a meta-field. For example, `Business.__typename` is *not* a valid +schema coordinate. Note: A {SchemaCoordinate} is not a definition within a GraphQL {Document}, but a separate standalone grammar, intended to be used by tools to reference types, From c16a28bc544d3892246b4fadbce0ee9382dc2e33 Mon Sep 17 00:00:00 2001 From: Lee Byron Date: Fri, 16 Apr 2021 09:29:35 -0700 Subject: [PATCH 19/46] Better Punctator --- spec/Appendix B -- Grammar Summary.md | 8 +++++++- spec/Section 2 -- Language.md | 15 ++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/spec/Appendix B -- Grammar Summary.md b/spec/Appendix B -- Grammar Summary.md index f9372bb9e..549991391 100644 --- a/spec/Appendix B -- Grammar Summary.md +++ b/spec/Appendix B -- Grammar Summary.md @@ -43,7 +43,13 @@ Token :: - FloatValue - StringValue -Punctuator :: one of ! $ & ( ) ... : = @ [ ] { | } . [lookahead != {`.`, Digit}] +Punctuator :: + - DotPunctuator + - OtherPunctuator + +DotPunctuator :: `.` [lookahead != {`.`, Digit}] + +OtherPunctuator :: one of ! $ & ( ) ... : = @ [ ] { | } Name :: diff --git a/spec/Section 2 -- Language.md b/spec/Section 2 -- Language.md index d64237e0d..9646c867b 100644 --- a/spec/Section 2 -- Language.md +++ b/spec/Section 2 -- Language.md @@ -176,12 +176,25 @@ and is {Ignored}. ### Punctuators -Punctuator :: one of ! $ & ( ) ... : = @ [ ] { | } . [lookahead != {`.`, Digit}] +Punctuator :: + +- DotPunctuator +- OtherPunctuator + +DotPunctuator :: `.` [lookahead != {`.`, Digit}] + +OtherPunctuator :: one of ! $ & ( ) ... : = @ [ ] { | } GraphQL documents include punctuation in order to describe structure. GraphQL is a data description language and not a programming language, therefore GraphQL lacks the punctuation often used to describe mathematical expressions. +The {`.`} punctuator must not be followed by a {`.`} or {Digit}. This +ensures that the source {"..."} can only be interpreted as a single {`...`} and +not three {`.`}. It also avoids any potential ambiguity with {FloatValue}. As +an example the source {".123"} has no valid lexical representation (without this +restriction it would have been interpreted as {`.`} followed by {IntValue}). + ### Names Name :: From 93bd2c6c6a86c2a9744eb7f8748655de4f3b9b41 Mon Sep 17 00:00:00 2001 From: Lee Byron Date: Thu, 22 Apr 2021 00:05:20 -0700 Subject: [PATCH 20/46] Minor algo variable name refinements --- spec/Section 3 -- Type System.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index d70efe1db..be4f4bddb 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2178,8 +2178,8 @@ SchemaCoordinate : :: A *schema coordinate* is a human readable string that uniquely identifies a *schema element* within a GraphQL Schema. -:: A *schema element* is a specific instance of a named type, type field, -input field, enum value, field argument, directive, or directive argument. +:: A *schema element* is a specific instance of a named type, field, input +field, enum value, field argument, directive, or directive argument. A *schema coordinate* is always unique. Each *schema element* may be referenced by exactly one possible schema coordinate. @@ -2225,8 +2225,8 @@ SchemaCoordinate : Name . Name ( Name : ) 4. Let {fieldName} be the value of the second {Name}. 5. Let {field} be the field of {type} named {fieldName}. 6. Assert {field} must exist. - 7. Let {argumentName} be the value of the third {Name}. - 8. Return the argument of {field} named {argumentName}. + 7. Let {fieldArgumentName} be the value of the third {Name}. + 8. Return the argument of {field} named {fieldArgumentName}. SchemaCoordinate : @ Name 1. Let {directiveName} be the value of the first {Name}. @@ -2236,15 +2236,15 @@ SchemaCoordinate : @ Name ( Name : ) 1. Let {directiveName} be the value of the first {Name}. 2. Let {directive} be the directive in the {schema} named {directiveName}. 3. Assert {directive} must exist. - 4. Let {argumentName} be the value of the second {Name}. - 5. Return the argument of {directive} named {argumentName}. + 4. Let {directiveArgumentName} be the value of the second {Name}. + 5. Return the argument of {directive} named {directiveArgumentName}. **Examples** | Element Kind | *Schema Coordinate* | *Schema Element* | | ------------------ | -------------------------------- | ----------------------------------------------------------------------- | | Named Type | `Business` | `Business` type | -| Type Field | `Business.name` | `name` field on the `Business` type | +| Field | `Business.name` | `name` field on the `Business` type | | Input Field | `SearchCriteria.filter` | `filter` input field on the `SearchCriteria` input object type | | Enum Value | `SearchFilter.OPEN_NOW` | `OPEN_NOW` value of the `SearchFilter` enum | | Field Argument | `Query.searchBusiness(criteria:)`| `criteria` argument on the `searchBusiness` field on the `Query` type | From b2e42e88dce5073cdc955f465f27ba62a0c2c342 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Tue, 10 Dec 2024 11:17:02 -0600 Subject: [PATCH 21/46] whitespace fix --- spec/Appendix B -- Grammar Summary.md | 4 ++-- spec/Section 3 -- Type System.md | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/spec/Appendix B -- Grammar Summary.md b/spec/Appendix B -- Grammar Summary.md index 549991391..d0777aac5 100644 --- a/spec/Appendix B -- Grammar Summary.md +++ b/spec/Appendix B -- Grammar Summary.md @@ -44,8 +44,8 @@ Token :: - StringValue Punctuator :: - - DotPunctuator - - OtherPunctuator +- DotPunctuator +- OtherPunctuator DotPunctuator :: `.` [lookahead != {`.`, Digit}] diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index be4f4bddb..07085ddb3 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -282,7 +282,6 @@ Schema extensions have the potential to be invalid if incorrectly defined. 2. Any non-repeatable directives provided must not already apply to the original Schema. - ## Types TypeDefinition : From 4ce2d48933e304799a84063b13317b3afd2b16a3 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Tue, 10 Dec 2024 11:37:20 -0600 Subject: [PATCH 22/46] add note about union members --- spec/Section 3 -- Type System.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 07085ddb3..89d7a80a6 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2181,7 +2181,7 @@ SchemaCoordinate : field, enum value, field argument, directive, or directive argument. A *schema coordinate* is always unique. Each *schema element* may be referenced -by exactly one possible schema coordinate. +by exactly one possible schema coordinate. There is a bidirectional 1:1 mapping. A *schema coordinate* may refer to either a defined or built-in *schema element*. For example, `String` and `@deprecated(reason:)` are both valid schema @@ -2189,10 +2189,16 @@ coordinates which refer to built-in schema elements. However it must not refer to a meta-field. For example, `Business.__typename` is *not* a valid schema coordinate. +Note: Unions members are not valid schema coordinates since they are references +to existing types in the schema. This preserves the 1:1 mapping property of +schema coordinates as stated above. + Note: A {SchemaCoordinate} is not a definition within a GraphQL {Document}, but a separate standalone grammar, intended to be used by tools to reference types, -fields, and other *schema element*s. For example as references within -documentation, or as lookup keys in usage frequency tracking. +fields, and other *schema element*s. Examples include: as references within +documentation to refer to types and fields in a schema, a lookup key that can +be used in logging tools to track how often particular fields are queried in +production. **Semantics** From 2d60b336531c1c98c5c31f96051711499b2bec3d Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Tue, 10 Dec 2024 11:40:13 -0600 Subject: [PATCH 23/46] prettier --- spec/Appendix B -- Grammar Summary.md | 2 + spec/Section 2 -- Language.md | 8 +- spec/Section 3 -- Type System.md | 120 ++++++++++++++------------ 3 files changed, 69 insertions(+), 61 deletions(-) diff --git a/spec/Appendix B -- Grammar Summary.md b/spec/Appendix B -- Grammar Summary.md index d0777aac5..22dab575e 100644 --- a/spec/Appendix B -- Grammar Summary.md +++ b/spec/Appendix B -- Grammar Summary.md @@ -44,6 +44,7 @@ Token :: - StringValue Punctuator :: + - DotPunctuator - OtherPunctuator @@ -420,6 +421,7 @@ TypeSystemDirectiveLocation : one of - `INPUT_FIELD_DEFINITION` SchemaCoordinate : + - Name - Name . Name - Name . Name ( Name : ) diff --git a/spec/Section 2 -- Language.md b/spec/Section 2 -- Language.md index 9646c867b..3c22f0e71 100644 --- a/spec/Section 2 -- Language.md +++ b/spec/Section 2 -- Language.md @@ -189,10 +189,10 @@ GraphQL documents include punctuation in order to describe structure. GraphQL is a data description language and not a programming language, therefore GraphQL lacks the punctuation often used to describe mathematical expressions. -The {`.`} punctuator must not be followed by a {`.`} or {Digit}. This -ensures that the source {"..."} can only be interpreted as a single {`...`} and -not three {`.`}. It also avoids any potential ambiguity with {FloatValue}. As -an example the source {".123"} has no valid lexical representation (without this +The {`.`} punctuator must not be followed by a {`.`} or {Digit}. This ensures +that the source {"..."} can only be interpreted as a single {`...`} and not +three {`.`}. It also avoids any potential ambiguity with {FloatValue}. As an +example the source {".123"} has no valid lexical representation (without this restriction it would have been interpreted as {`.`} followed by {IntValue}). ### Names diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 89d7a80a6..ce75b331e 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2168,26 +2168,27 @@ scalar UUID @specifiedBy(url: "https://tools.ietf.org/html/rfc4122") ## Schema Coordinates SchemaCoordinate : - - Name - - Name . Name - - Name . Name ( Name : ) - - @ Name - - @ Name ( Name : ) -:: A *schema coordinate* is a human readable string that uniquely identifies a -*schema element* within a GraphQL Schema. +- Name +- Name . Name +- Name . Name ( Name : ) +- @ Name +- @ Name ( Name : ) -:: A *schema element* is a specific instance of a named type, field, input +:: A _schema coordinate_ is a human readable string that uniquely identifies a +_schema element_ within a GraphQL Schema. + +:: A _schema element_ is a specific instance of a named type, field, input field, enum value, field argument, directive, or directive argument. -A *schema coordinate* is always unique. Each *schema element* may be referenced +A _schema coordinate_ is always unique. Each _schema element_ may be referenced by exactly one possible schema coordinate. There is a bidirectional 1:1 mapping. -A *schema coordinate* may refer to either a defined or built-in *schema element*. -For example, `String` and `@deprecated(reason:)` are both valid schema +A _schema coordinate_ may refer to either a defined or built-in _schema +element_. For example, `String` and `@deprecated(reason:)` are both valid schema coordinates which refer to built-in schema elements. However it must not refer -to a meta-field. For example, `Business.__typename` is *not* a valid -schema coordinate. +to a meta-field. For example, `Business.__typename` is _not_ a valid schema +coordinate. Note: Unions members are not valid schema coordinates since they are references to existing types in the schema. This preserves the 1:1 mapping property of @@ -2196,68 +2197,73 @@ schema coordinates as stated above. Note: A {SchemaCoordinate} is not a definition within a GraphQL {Document}, but a separate standalone grammar, intended to be used by tools to reference types, fields, and other *schema element*s. Examples include: as references within -documentation to refer to types and fields in a schema, a lookup key that can -be used in logging tools to track how often particular fields are queried in +documentation to refer to types and fields in a schema, a lookup key that can be +used in logging tools to track how often particular fields are queried in production. **Semantics** -To refer to a *schema element*, a *schema coordinate* must be interpreted in the +To refer to a _schema element_, a _schema coordinate_ must be interpreted in the context of a GraphQL {schema}. SchemaCoordinate : Name - 1. Let {typeName} be the value of the first {Name}. - 2. Return the type in the {schema} named {typeName}. + +1. Let {typeName} be the value of the first {Name}. +2. Return the type in the {schema} named {typeName}. SchemaCoordinate : Name . Name - 1. Let {typeName} be the value of the first {Name}. - 2. Let {type} be the type in the {schema} named {typeName}. - 3. If {type} is an Enum type: - 1. Let {enumValueName} be the value of the second {Name}. - 2. Return the enum value of {type} named {enumValueName}. - 4. Otherwise if {type} is an Input Object type: - 1. Let {inputFieldName} be the value of the second {Name}. - 2. Return the input field of {type} named {inputFieldName}. - 5. Otherwise: - 1. Assert {type} must be an Object or Interface type. - 2. Let {fieldName} be the value of the second {Name}. - 3. Return the field of {type} named {fieldName}. + +1. Let {typeName} be the value of the first {Name}. +2. Let {type} be the type in the {schema} named {typeName}. +3. If {type} is an Enum type: +4. Let {enumValueName} be the value of the second {Name}. +5. Return the enum value of {type} named {enumValueName}. +6. Otherwise if {type} is an Input Object type: +7. Let {inputFieldName} be the value of the second {Name}. +8. Return the input field of {type} named {inputFieldName}. +9. Otherwise: +10. Assert {type} must be an Object or Interface type. +11. Let {fieldName} be the value of the second {Name}. +12. Return the field of {type} named {fieldName}. SchemaCoordinate : Name . Name ( Name : ) - 1. Let {typeName} be the value of the first {Name}. - 2. Let {type} be the type in the {schema} named {typeName}. - 3. Assert {type} must be an Object or Interface type. - 4. Let {fieldName} be the value of the second {Name}. - 5. Let {field} be the field of {type} named {fieldName}. - 6. Assert {field} must exist. - 7. Let {fieldArgumentName} be the value of the third {Name}. - 8. Return the argument of {field} named {fieldArgumentName}. + +1. Let {typeName} be the value of the first {Name}. +2. Let {type} be the type in the {schema} named {typeName}. +3. Assert {type} must be an Object or Interface type. +4. Let {fieldName} be the value of the second {Name}. +5. Let {field} be the field of {type} named {fieldName}. +6. Assert {field} must exist. +7. Let {fieldArgumentName} be the value of the third {Name}. +8. Return the argument of {field} named {fieldArgumentName}. SchemaCoordinate : @ Name - 1. Let {directiveName} be the value of the first {Name}. - 2. Return the directive in the {schema} named {directiveName}. + +1. Let {directiveName} be the value of the first {Name}. +2. Return the directive in the {schema} named {directiveName}. SchemaCoordinate : @ Name ( Name : ) - 1. Let {directiveName} be the value of the first {Name}. - 2. Let {directive} be the directive in the {schema} named {directiveName}. - 3. Assert {directive} must exist. - 4. Let {directiveArgumentName} be the value of the second {Name}. - 5. Return the argument of {directive} named {directiveArgumentName}. + +1. Let {directiveName} be the value of the first {Name}. +2. Let {directive} be the directive in the {schema} named {directiveName}. +3. Assert {directive} must exist. +4. Let {directiveArgumentName} be the value of the second {Name}. +5. Return the argument of {directive} named {directiveArgumentName}. **Examples** -| Element Kind | *Schema Coordinate* | *Schema Element* | -| ------------------ | -------------------------------- | ----------------------------------------------------------------------- | -| Named Type | `Business` | `Business` type | -| Field | `Business.name` | `name` field on the `Business` type | -| Input Field | `SearchCriteria.filter` | `filter` input field on the `SearchCriteria` input object type | -| Enum Value | `SearchFilter.OPEN_NOW` | `OPEN_NOW` value of the `SearchFilter` enum | -| Field Argument | `Query.searchBusiness(criteria:)`| `criteria` argument on the `searchBusiness` field on the `Query` type | -| Directive | `@private` | `@private` directive | -| Directive Argument | `@private(scope:)` | `scope` argument on the `@private` directive | - -The table above shows an example of a *schema coordinate* for every kind of -*schema element* based on the schema below. +| Element Kind | _Schema Coordinate_ | _Schema Element_ | +| ------------------ | --------------------------------- | --------------------------------------------------------------------- | +| Named Type | `Business` | `Business` type | +| Field | `Business.name` | `name` field on the `Business` type | +| Input Field | `SearchCriteria.filter` | `filter` input field on the `SearchCriteria` input object type | +| Enum Value | `SearchFilter.OPEN_NOW` | `OPEN_NOW` value of the `SearchFilter` enum | +| Field Argument | `Query.searchBusiness(criteria:)` | `criteria` argument on the `searchBusiness` field on the `Query` type | +| Directive | `@private` | `@private` directive | +| Directive Argument | `@private(scope:)` | `scope` argument on the `@private` directive | + +The table above shows an example of a _schema coordinate_ for every kind of +_schema element_ based on the schema below. ```graphql type Query { From d61cdc3153d94912a6b2e11c643f9b24667965b1 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Tue, 10 Dec 2024 11:49:01 -0600 Subject: [PATCH 24/46] formatting --- spec/Section 3 -- Type System.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index ce75b331e..ef1eeea43 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2182,7 +2182,7 @@ _schema element_ within a GraphQL Schema. field, enum value, field argument, directive, or directive argument. A _schema coordinate_ is always unique. Each _schema element_ may be referenced -by exactly one possible schema coordinate. There is a bidirectional 1:1 mapping. +by exactly one possible schema coordinate. A _schema coordinate_ may refer to either a defined or built-in _schema element_. For example, `String` and `@deprecated(reason:)` are both valid schema @@ -2190,9 +2190,9 @@ coordinates which refer to built-in schema elements. However it must not refer to a meta-field. For example, `Business.__typename` is _not_ a valid schema coordinate. -Note: Unions members are not valid schema coordinates since they are references -to existing types in the schema. This preserves the 1:1 mapping property of -schema coordinates as stated above. +Note: A union member is not a valid _schema coordinate_ as they reference +existing types in the schema. This preserves the uniqueness property of a +_schema coordinate_ as stated above. Note: A {SchemaCoordinate} is not a definition within a GraphQL {Document}, but a separate standalone grammar, intended to be used by tools to reference types, From caed065f874559a9bb87bc38c7365605fcd4682c Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Thu, 2 Jan 2025 09:51:45 -0600 Subject: [PATCH 25/46] Update spec/Section 3 -- Type System.md Co-authored-by: Martin Bonnin --- spec/Section 3 -- Type System.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index ef1eeea43..25f63467a 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2178,8 +2178,8 @@ SchemaCoordinate : :: A _schema coordinate_ is a human readable string that uniquely identifies a _schema element_ within a GraphQL Schema. -:: A _schema element_ is a specific instance of a named type, field, input -field, enum value, field argument, directive, or directive argument. +:: A _schema element_ can be a named type, a field, an input +a field, an enum value, a field argument, a directive, or a directive argument. A _schema coordinate_ is always unique. Each _schema element_ may be referenced by exactly one possible schema coordinate. From 07b3bbdac29f23445be4084431d9aff7bebbf57b Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Thu, 2 Jan 2025 10:14:20 -0600 Subject: [PATCH 26/46] Update spec/Section 3 -- Type System.md Co-authored-by: Martin Bonnin --- spec/Section 3 -- Type System.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 25f63467a..9f2476e6c 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2178,8 +2178,8 @@ SchemaCoordinate : :: A _schema coordinate_ is a human readable string that uniquely identifies a _schema element_ within a GraphQL Schema. -:: A _schema element_ can be a named type, a field, an input -a field, an enum value, a field argument, a directive, or a directive argument. +:: A _schema element_ can be a named type, a field, an input +field, an enum value, a field argument, a directive, or a directive argument. A _schema coordinate_ is always unique. Each _schema element_ may be referenced by exactly one possible schema coordinate. From 258d8413dd567d93cb51b26dd9a36bac78e5d8aa Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Fri, 16 May 2025 09:37:51 +0100 Subject: [PATCH 27/46] Run prettier --- spec/Section 3 -- Type System.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index d26eec13c..f4e2b0166 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2182,8 +2182,8 @@ SchemaCoordinate : :: A _schema coordinate_ is a human readable string that uniquely identifies a _schema element_ within a GraphQL Schema. -:: A _schema element_ can be a named type, a field, an input -field, an enum value, a field argument, a directive, or a directive argument. +:: A _schema element_ can be a named type, a field, an input field, an enum +value, a field argument, a directive, or a directive argument. A _schema coordinate_ is always unique. Each _schema element_ may be referenced by exactly one possible schema coordinate. From 8a97138dfb099b82d8bbb2d9591827d98db95cc9 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Sun, 1 Jun 2025 22:37:27 -0500 Subject: [PATCH 28/46] add spec updates --- spec/Section 3 -- Type System.md | 53 ++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index f4e2b0166..8c19ad0aa 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2185,7 +2185,7 @@ _schema element_ within a GraphQL Schema. :: A _schema element_ can be a named type, a field, an input field, an enum value, a field argument, a directive, or a directive argument. -A _schema coordinate_ is always unique. Each _schema element_ may be referenced +A _schema coordinate_ is always unique. Each _schema element_ can be referenced by exactly one possible schema coordinate. A _schema coordinate_ may refer to either a defined or built-in _schema @@ -2205,30 +2205,44 @@ documentation to refer to types and fields in a schema, a lookup key that can be used in logging tools to track how often particular fields are queried in production. -**Semantics** +**Resolving a Schema Coordinate** To refer to a _schema element_, a _schema coordinate_ must be interpreted in the context of a GraphQL {schema}. +Note: If the _schema element_ cannot be found, the resolve function will not +yield a value (without raising an error). However, an error **will** be raised +if any non-leaf nodes within a _schema coordinate_ cannot be found in the +{schema}. + SchemaCoordinate : Name 1. Let {typeName} be the value of the first {Name}. -2. Return the type in the {schema} named {typeName}. +2. Let {type} be the type in the {schema} named {typeName}. +3. If {type} does not exist, return {void}. +4. Return {type} SchemaCoordinate : Name . Name 1. Let {typeName} be the value of the first {Name}. 2. Let {type} be the type in the {schema} named {typeName}. -3. If {type} is an Enum type: -4. Let {enumValueName} be the value of the second {Name}. -5. Return the enum value of {type} named {enumValueName}. -6. Otherwise if {type} is an Input Object type: -7. Let {inputFieldName} be the value of the second {Name}. -8. Return the input field of {type} named {inputFieldName}. -9. Otherwise: -10. Assert {type} must be an Object or Interface type. -11. Let {fieldName} be the value of the second {Name}. -12. Return the field of {type} named {fieldName}. +3. Assert that {type} exists. +4. If {type} is an Enum type: +5. Let {enumValueName} be the value of the second {Name}. +6. Let {enumValue} be the enum value of {type} named {enumValueName}. +7. If {enumValue} does not exist, return {void}. +8. Return {enumValue} +9. Otherwise if {type} is an Input Object type: +10. Let {inputFieldName} be the value of the second {Name}. +11. Let {inputField} be the input field of {type} named {inputFieldName}. +12. If {inputField} does not exist, return {void}. +13. Return {inputField} +14. Otherwise: +15. Assert {type} must be an Object or Interface type. +16. Let {fieldName} be the value of the second {Name}. +17. Let {field} be the field of {type} named {fieldName}. +18. If {field} does not exist, return {void}. +19. Return {field} SchemaCoordinate : Name . Name ( Name : ) @@ -2239,12 +2253,16 @@ SchemaCoordinate : Name . Name ( Name : ) 5. Let {field} be the field of {type} named {fieldName}. 6. Assert {field} must exist. 7. Let {fieldArgumentName} be the value of the third {Name}. -8. Return the argument of {field} named {fieldArgumentName}. +8. Let {fieldArgument} be the argument of {field} named {fieldArgumentName}. +9. If {fieldArgument} does not exist, return {void}. +10. Return {fieldArgument}. SchemaCoordinate : @ Name 1. Let {directiveName} be the value of the first {Name}. -2. Return the directive in the {schema} named {directiveName}. +2. Let {directive} be the directive in the {schema} named {directiveName}. +3. If {directive} does not exist, return {void}. +4. Return {directive}. SchemaCoordinate : @ Name ( Name : ) @@ -2252,7 +2270,10 @@ SchemaCoordinate : @ Name ( Name : ) 2. Let {directive} be the directive in the {schema} named {directiveName}. 3. Assert {directive} must exist. 4. Let {directiveArgumentName} be the value of the second {Name}. -5. Return the argument of {directive} named {directiveArgumentName}. +5. Let {directiveArgument} be the argument of {directive} named + {directiveArgumentName}. +6. If {directiveArgument} does not exist, return {void}. +7. Return {directiveArgument}. **Examples** From c8a2cfeb5f1a0b9826076e89563e3f7d243ab45f Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Sun, 1 Jun 2025 22:46:49 -0500 Subject: [PATCH 29/46] Add back assertion --- spec/Section 3 -- Type System.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 8c19ad0aa..17fa8786c 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2248,14 +2248,15 @@ SchemaCoordinate : Name . Name ( Name : ) 1. Let {typeName} be the value of the first {Name}. 2. Let {type} be the type in the {schema} named {typeName}. -3. Assert {type} must be an Object or Interface type. -4. Let {fieldName} be the value of the second {Name}. -5. Let {field} be the field of {type} named {fieldName}. -6. Assert {field} must exist. -7. Let {fieldArgumentName} be the value of the third {Name}. -8. Let {fieldArgument} be the argument of {field} named {fieldArgumentName}. -9. If {fieldArgument} does not exist, return {void}. -10. Return {fieldArgument}. +3. Assert that {type} exists. +4. Assert {type} must be an Object or Interface type. +5. Let {fieldName} be the value of the second {Name}. +6. Let {field} be the field of {type} named {fieldName}. +7. Assert {field} must exist. +8. Let {fieldArgumentName} be the value of the third {Name}. +9. Let {fieldArgument} be the argument of {field} named {fieldArgumentName}. +10. If {fieldArgument} does not exist, return {void}. +11. Return {fieldArgument}. SchemaCoordinate : @ Name From a96836aa8877084643fa292f5d29b9cf4903c10c Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Sun, 1 Jun 2025 23:01:57 -0500 Subject: [PATCH 30/46] assert that ... -> assert ... --- spec/Section 3 -- Type System.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 17fa8786c..073a996a5 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2226,7 +2226,7 @@ SchemaCoordinate : Name . Name 1. Let {typeName} be the value of the first {Name}. 2. Let {type} be the type in the {schema} named {typeName}. -3. Assert that {type} exists. +3. Assert {type} exists. 4. If {type} is an Enum type: 5. Let {enumValueName} be the value of the second {Name}. 6. Let {enumValue} be the enum value of {type} named {enumValueName}. @@ -2248,7 +2248,7 @@ SchemaCoordinate : Name . Name ( Name : ) 1. Let {typeName} be the value of the first {Name}. 2. Let {type} be the type in the {schema} named {typeName}. -3. Assert that {type} exists. +3. Assert {type} exists. 4. Assert {type} must be an Object or Interface type. 5. Let {fieldName} be the value of the second {Name}. 6. Let {field} be the field of {type} named {fieldName}. From 3effd4ab31b8163f71b2f165016f9c56c63889a3 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Sun, 1 Jun 2025 23:03:49 -0500 Subject: [PATCH 31/46] consistent periods --- spec/Section 3 -- Type System.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 073a996a5..786fcd010 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2220,7 +2220,7 @@ SchemaCoordinate : Name 1. Let {typeName} be the value of the first {Name}. 2. Let {type} be the type in the {schema} named {typeName}. 3. If {type} does not exist, return {void}. -4. Return {type} +4. Return {type}. SchemaCoordinate : Name . Name @@ -2231,18 +2231,18 @@ SchemaCoordinate : Name . Name 5. Let {enumValueName} be the value of the second {Name}. 6. Let {enumValue} be the enum value of {type} named {enumValueName}. 7. If {enumValue} does not exist, return {void}. -8. Return {enumValue} +8. Return {enumValue}. 9. Otherwise if {type} is an Input Object type: 10. Let {inputFieldName} be the value of the second {Name}. 11. Let {inputField} be the input field of {type} named {inputFieldName}. 12. If {inputField} does not exist, return {void}. -13. Return {inputField} +13. Return {inputField}. 14. Otherwise: 15. Assert {type} must be an Object or Interface type. 16. Let {fieldName} be the value of the second {Name}. 17. Let {field} be the field of {type} named {fieldName}. 18. If {field} does not exist, return {void}. -19. Return {field} +19. Return {field}. SchemaCoordinate : Name . Name ( Name : ) @@ -2271,7 +2271,7 @@ SchemaCoordinate : @ Name ( Name : ) 2. Let {directive} be the directive in the {schema} named {directiveName}. 3. Assert {directive} must exist. 4. Let {directiveArgumentName} be the value of the second {Name}. -5. Let {directiveArgument} be the argument of {directive} named +5. Let {directiveArgument} be the argument of {directive} named. {directiveArgumentName}. 6. If {directiveArgument} does not exist, return {void}. 7. Return {directiveArgument}. From 9feceb2bbe08c5593f423ecc59803de7a3ec20b5 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Sun, 1 Jun 2025 23:05:02 -0500 Subject: [PATCH 32/46] consistent exists/must exist --- spec/Section 3 -- Type System.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 786fcd010..dc270f341 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2226,7 +2226,7 @@ SchemaCoordinate : Name . Name 1. Let {typeName} be the value of the first {Name}. 2. Let {type} be the type in the {schema} named {typeName}. -3. Assert {type} exists. +3. Assert {type} must exist. 4. If {type} is an Enum type: 5. Let {enumValueName} be the value of the second {Name}. 6. Let {enumValue} be the enum value of {type} named {enumValueName}. @@ -2248,7 +2248,7 @@ SchemaCoordinate : Name . Name ( Name : ) 1. Let {typeName} be the value of the first {Name}. 2. Let {type} be the type in the {schema} named {typeName}. -3. Assert {type} exists. +3. Assert {type} must exist. 4. Assert {type} must be an Object or Interface type. 5. Let {fieldName} be the value of the second {Name}. 6. Let {field} be the field of {type} named {fieldName}. From 11b9e96f85658f470d226cb707eb2a0ecf948d5c Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Sun, 1 Jun 2025 23:14:53 -0500 Subject: [PATCH 33/46] void -> null --- spec/Section 3 -- Type System.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index dc270f341..7e3c4cb77 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2219,7 +2219,7 @@ SchemaCoordinate : Name 1. Let {typeName} be the value of the first {Name}. 2. Let {type} be the type in the {schema} named {typeName}. -3. If {type} does not exist, return {void}. +3. If {type} does not exist, return {null}. 4. Return {type}. SchemaCoordinate : Name . Name @@ -2230,18 +2230,18 @@ SchemaCoordinate : Name . Name 4. If {type} is an Enum type: 5. Let {enumValueName} be the value of the second {Name}. 6. Let {enumValue} be the enum value of {type} named {enumValueName}. -7. If {enumValue} does not exist, return {void}. +7. If {enumValue} does not exist, return {null}. 8. Return {enumValue}. 9. Otherwise if {type} is an Input Object type: 10. Let {inputFieldName} be the value of the second {Name}. 11. Let {inputField} be the input field of {type} named {inputFieldName}. -12. If {inputField} does not exist, return {void}. +12. If {inputField} does not exist, return {null}. 13. Return {inputField}. 14. Otherwise: 15. Assert {type} must be an Object or Interface type. 16. Let {fieldName} be the value of the second {Name}. 17. Let {field} be the field of {type} named {fieldName}. -18. If {field} does not exist, return {void}. +18. If {field} does not exist, return {null}. 19. Return {field}. SchemaCoordinate : Name . Name ( Name : ) @@ -2255,14 +2255,14 @@ SchemaCoordinate : Name . Name ( Name : ) 7. Assert {field} must exist. 8. Let {fieldArgumentName} be the value of the third {Name}. 9. Let {fieldArgument} be the argument of {field} named {fieldArgumentName}. -10. If {fieldArgument} does not exist, return {void}. +10. If {fieldArgument} does not exist, return {null}. 11. Return {fieldArgument}. SchemaCoordinate : @ Name 1. Let {directiveName} be the value of the first {Name}. 2. Let {directive} be the directive in the {schema} named {directiveName}. -3. If {directive} does not exist, return {void}. +3. If {directive} does not exist, return {null}. 4. Return {directive}. SchemaCoordinate : @ Name ( Name : ) @@ -2273,7 +2273,7 @@ SchemaCoordinate : @ Name ( Name : ) 4. Let {directiveArgumentName} be the value of the second {Name}. 5. Let {directiveArgument} be the argument of {directive} named. {directiveArgumentName}. -6. If {directiveArgument} does not exist, return {void}. +6. If {directiveArgument} does not exist, return {null}. 7. Return {directiveArgument}. **Examples** From 10742dd44edee9f25ceb24d8e32da7459525bb71 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Sun, 1 Jun 2025 23:17:47 -0500 Subject: [PATCH 34/46] remove note prefix for error throwing note --- spec/Section 3 -- Type System.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 7e3c4cb77..cc0f8fed4 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2210,10 +2210,9 @@ production. To refer to a _schema element_, a _schema coordinate_ must be interpreted in the context of a GraphQL {schema}. -Note: If the _schema element_ cannot be found, the resolve function will not -yield a value (without raising an error). However, an error **will** be raised -if any non-leaf nodes within a _schema coordinate_ cannot be found in the -{schema}. +If the _schema element_ cannot be found, the resolve function will not yield a +value (without raising an error). However, an error **will** be raised if any +non-leaf nodes within a _schema coordinate_ cannot be found in the {schema}. SchemaCoordinate : Name From 4b9f37aa118b2b42ecaa388907ea6562b7de13bc Mon Sep 17 00:00:00 2001 From: Benjie Date: Mon, 2 Jun 2025 06:33:36 +0100 Subject: [PATCH 35/46] Various stylistic fixes --- spec/Section 3 -- Type System.md | 46 ++++++++++++++++---------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index cc0f8fed4..50dd95c44 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2200,7 +2200,7 @@ _schema coordinate_ as stated above. Note: A {SchemaCoordinate} is not a definition within a GraphQL {Document}, but a separate standalone grammar, intended to be used by tools to reference types, -fields, and other *schema element*s. Examples include: as references within +fields, and other _schema element_. Examples include: references within documentation to refer to types and fields in a schema, a lookup key that can be used in logging tools to track how often particular fields are queried in production. @@ -2211,7 +2211,7 @@ To refer to a _schema element_, a _schema coordinate_ must be interpreted in the context of a GraphQL {schema}. If the _schema element_ cannot be found, the resolve function will not yield a -value (without raising an error). However, an error **will** be raised if any +value (without raising an error). However, an error will be raised if any non-leaf nodes within a _schema coordinate_ cannot be found in the {schema}. SchemaCoordinate : Name @@ -2225,33 +2225,33 @@ SchemaCoordinate : Name . Name 1. Let {typeName} be the value of the first {Name}. 2. Let {type} be the type in the {schema} named {typeName}. -3. Assert {type} must exist. +3. Assert: {type} must exist. 4. If {type} is an Enum type: -5. Let {enumValueName} be the value of the second {Name}. -6. Let {enumValue} be the enum value of {type} named {enumValueName}. -7. If {enumValue} does not exist, return {null}. -8. Return {enumValue}. -9. Otherwise if {type} is an Input Object type: -10. Let {inputFieldName} be the value of the second {Name}. -11. Let {inputField} be the input field of {type} named {inputFieldName}. -12. If {inputField} does not exist, return {null}. -13. Return {inputField}. -14. Otherwise: -15. Assert {type} must be an Object or Interface type. -16. Let {fieldName} be the value of the second {Name}. -17. Let {field} be the field of {type} named {fieldName}. -18. If {field} does not exist, return {null}. -19. Return {field}. + 1. Let {enumValueName} be the value of the second {Name}. + 2. Let {enumValue} be the enum value of {type} named {enumValueName}. + 3. If {enumValue} does not exist, return {null}. + 4. Return {enumValue}. +5. Otherwise, if {type} is an Input Object type: + 1. Let {inputFieldName} be the value of the second {Name}. + 2. Let {inputField} be the input field of {type} named {inputFieldName}. + 3. If {inputField} does not exist, return {null}. + 4. Return {inputField}. +6. Otherwise: + 1. Assert: {type} must be an Object or Interface type. + 2. Let {fieldName} be the value of the second {Name}. + 3. Let {field} be the field of {type} named {fieldName}. + 4. If {field} does not exist, return {null}. + 5. Return {field}. SchemaCoordinate : Name . Name ( Name : ) 1. Let {typeName} be the value of the first {Name}. 2. Let {type} be the type in the {schema} named {typeName}. -3. Assert {type} must exist. -4. Assert {type} must be an Object or Interface type. +3. Assert: {type} must exist. +4. Assert: {type} must be an Object or Interface type. 5. Let {fieldName} be the value of the second {Name}. 6. Let {field} be the field of {type} named {fieldName}. -7. Assert {field} must exist. +7. Assert: {field} must exist. 8. Let {fieldArgumentName} be the value of the third {Name}. 9. Let {fieldArgument} be the argument of {field} named {fieldArgumentName}. 10. If {fieldArgument} does not exist, return {null}. @@ -2268,9 +2268,9 @@ SchemaCoordinate : @ Name ( Name : ) 1. Let {directiveName} be the value of the first {Name}. 2. Let {directive} be the directive in the {schema} named {directiveName}. -3. Assert {directive} must exist. +3. Assert: {directive} must exist. 4. Let {directiveArgumentName} be the value of the second {Name}. -5. Let {directiveArgument} be the argument of {directive} named. +5. Let {directiveArgument} be the argument of {directive} named {directiveArgumentName}. 6. If {directiveArgument} does not exist, return {null}. 7. Return {directiveArgument}. From 3555f575a219a20e9421f3a9c1fec2baa7536f79 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Mon, 2 Jun 2025 10:06:01 -0500 Subject: [PATCH 36/46] Update spec/Section 3 -- Type System.md Co-authored-by: Benoit 'BoD' Lubek --- spec/Section 3 -- Type System.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 50dd95c44..61fe9d0f8 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2194,7 +2194,7 @@ coordinates which refer to built-in schema elements. However it must not refer to a meta-field. For example, `Business.__typename` is _not_ a valid schema coordinate. -Note: A union member is not a valid _schema coordinate_ as they reference +Note: Union members are not valid _schema coordinates_ as they reference existing types in the schema. This preserves the uniqueness property of a _schema coordinate_ as stated above. From a52e312089ffe820650f3ac9638ad0b2ed45988a Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Mon, 2 Jun 2025 10:08:02 -0500 Subject: [PATCH 37/46] Update spec/Section 3 -- Type System.md Co-authored-by: Benoit 'BoD' Lubek --- spec/Section 3 -- Type System.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 61fe9d0f8..e0f1b2400 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2216,7 +2216,7 @@ non-leaf nodes within a _schema coordinate_ cannot be found in the {schema}. SchemaCoordinate : Name -1. Let {typeName} be the value of the first {Name}. +1. Let {typeName} be the value of {Name}. 2. Let {type} be the type in the {schema} named {typeName}. 3. If {type} does not exist, return {null}. 4. Return {type}. From dc1374d385b670f5601868ec41b8de28332eb645 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Mon, 2 Jun 2025 10:09:26 -0500 Subject: [PATCH 38/46] Apply benjie's suggestions from code review Co-authored-by: Benjie --- spec/Section 3 -- Type System.md | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index e0f1b2400..78a926422 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2217,9 +2217,7 @@ non-leaf nodes within a _schema coordinate_ cannot be found in the {schema}. SchemaCoordinate : Name 1. Let {typeName} be the value of {Name}. -2. Let {type} be the type in the {schema} named {typeName}. -3. If {type} does not exist, return {null}. -4. Return {type}. +2. Return the type in the {schema} named {typeName}, or {null} if no such type exists. SchemaCoordinate : Name . Name @@ -2228,20 +2226,14 @@ SchemaCoordinate : Name . Name 3. Assert: {type} must exist. 4. If {type} is an Enum type: 1. Let {enumValueName} be the value of the second {Name}. - 2. Let {enumValue} be the enum value of {type} named {enumValueName}. - 3. If {enumValue} does not exist, return {null}. - 4. Return {enumValue}. + 2. Return the enum value of {type} named {enumValueName}, or {null} if no such value exists. 5. Otherwise, if {type} is an Input Object type: 1. Let {inputFieldName} be the value of the second {Name}. - 2. Let {inputField} be the input field of {type} named {inputFieldName}. - 3. If {inputField} does not exist, return {null}. - 4. Return {inputField}. + 2. Return the input field of {type} named {inputFieldName}, or {null} if no such input field exists. 6. Otherwise: 1. Assert: {type} must be an Object or Interface type. 2. Let {fieldName} be the value of the second {Name}. - 3. Let {field} be the field of {type} named {fieldName}. - 4. If {field} does not exist, return {null}. - 5. Return {field}. + 3. Return the field of {type} named {fieldName}, or {null} if no such field exists. SchemaCoordinate : Name . Name ( Name : ) @@ -2253,16 +2245,12 @@ SchemaCoordinate : Name . Name ( Name : ) 6. Let {field} be the field of {type} named {fieldName}. 7. Assert: {field} must exist. 8. Let {fieldArgumentName} be the value of the third {Name}. -9. Let {fieldArgument} be the argument of {field} named {fieldArgumentName}. -10. If {fieldArgument} does not exist, return {null}. -11. Return {fieldArgument}. +9. Return the argument of {field} named {fieldArgumentName}, or {null} if no such argument exists. SchemaCoordinate : @ Name 1. Let {directiveName} be the value of the first {Name}. -2. Let {directive} be the directive in the {schema} named {directiveName}. -3. If {directive} does not exist, return {null}. -4. Return {directive}. +2. Return the directive in the {schema} named {directiveName}, or {null} if no such directive exists. SchemaCoordinate : @ Name ( Name : ) @@ -2270,10 +2258,8 @@ SchemaCoordinate : @ Name ( Name : ) 2. Let {directive} be the directive in the {schema} named {directiveName}. 3. Assert: {directive} must exist. 4. Let {directiveArgumentName} be the value of the second {Name}. -5. Let {directiveArgument} be the argument of {directive} named - {directiveArgumentName}. -6. If {directiveArgument} does not exist, return {null}. -7. Return {directiveArgument}. +5. Return the argument of {directive} named + {directiveArgumentName}, or {null} if no such argument exists. **Examples** From 8c018027fc1e1d0ff926f631056183e6f9974202 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Mon, 2 Jun 2025 10:22:00 -0500 Subject: [PATCH 39/46] split out SchemaCoordinate definition --- spec/Section 3 -- Type System.md | 58 ++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 78a926422..ad21ef29e 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2173,11 +2173,21 @@ scalar UUID @specifiedBy(url: "https://tools.ietf.org/html/rfc4122") SchemaCoordinate : -- Name -- Name . Name -- Name . Name ( Name : ) -- @ Name -- @ Name ( Name : ) +- TypeCoordinate +- MemberCoordinate +- ArgumentCoordinate +- DirectiveCoordinate +- DirectiveArgumentCoordinate + +TypeCoordinate : Name + +MemberCoordinate : Name . Name + +ArgumentCoordinate : Name . Name ( Name : ) + +DirectiveCoordinate : @ Name + +DirectiveArgumentCoordinate : @ Name ( Name : ) :: A _schema coordinate_ is a human readable string that uniquely identifies a _schema element_ within a GraphQL Schema. @@ -2194,9 +2204,9 @@ coordinates which refer to built-in schema elements. However it must not refer to a meta-field. For example, `Business.__typename` is _not_ a valid schema coordinate. -Note: Union members are not valid _schema coordinates_ as they reference -existing types in the schema. This preserves the uniqueness property of a -_schema coordinate_ as stated above. +Note: Union members are not valid _schema coordinate_ as they reference existing +types in the schema. This preserves the uniqueness property of a _schema +coordinate_ as stated above. Note: A {SchemaCoordinate} is not a definition within a GraphQL {Document}, but a separate standalone grammar, intended to be used by tools to reference types, @@ -2214,28 +2224,32 @@ If the _schema element_ cannot be found, the resolve function will not yield a value (without raising an error). However, an error will be raised if any non-leaf nodes within a _schema coordinate_ cannot be found in the {schema}. -SchemaCoordinate : Name +TypeCoordinate : Name 1. Let {typeName} be the value of {Name}. -2. Return the type in the {schema} named {typeName}, or {null} if no such type exists. +2. Return the type in the {schema} named {typeName}, or {null} if no such type + exists. -SchemaCoordinate : Name . Name +MemberCoordinate : Name . Name 1. Let {typeName} be the value of the first {Name}. 2. Let {type} be the type in the {schema} named {typeName}. 3. Assert: {type} must exist. 4. If {type} is an Enum type: 1. Let {enumValueName} be the value of the second {Name}. - 2. Return the enum value of {type} named {enumValueName}, or {null} if no such value exists. + 2. Return the enum value of {type} named {enumValueName}, or {null} if no + such value exists. 5. Otherwise, if {type} is an Input Object type: 1. Let {inputFieldName} be the value of the second {Name}. - 2. Return the input field of {type} named {inputFieldName}, or {null} if no such input field exists. + 2. Return the input field of {type} named {inputFieldName}, or {null} if no + such input field exists. 6. Otherwise: 1. Assert: {type} must be an Object or Interface type. 2. Let {fieldName} be the value of the second {Name}. - 3. Return the field of {type} named {fieldName}, or {null} if no such field exists. + 3. Return the field of {type} named {fieldName}, or {null} if no such field + exists. -SchemaCoordinate : Name . Name ( Name : ) +ArgumentCoordinate : Name . Name ( Name : ) 1. Let {typeName} be the value of the first {Name}. 2. Let {type} be the type in the {schema} named {typeName}. @@ -2245,21 +2259,23 @@ SchemaCoordinate : Name . Name ( Name : ) 6. Let {field} be the field of {type} named {fieldName}. 7. Assert: {field} must exist. 8. Let {fieldArgumentName} be the value of the third {Name}. -9. Return the argument of {field} named {fieldArgumentName}, or {null} if no such argument exists. +9. Return the argument of {field} named {fieldArgumentName}, or {null} if no + such argument exists. -SchemaCoordinate : @ Name +DirectiveCoordinate : @ Name 1. Let {directiveName} be the value of the first {Name}. -2. Return the directive in the {schema} named {directiveName}, or {null} if no such directive exists. +2. Return the directive in the {schema} named {directiveName}, or {null} if no + such directive exists. -SchemaCoordinate : @ Name ( Name : ) +DirectiveArgumentCoordinate : @ Name ( Name : ) 1. Let {directiveName} be the value of the first {Name}. 2. Let {directive} be the directive in the {schema} named {directiveName}. 3. Assert: {directive} must exist. 4. Let {directiveArgumentName} be the value of the second {Name}. -5. Return the argument of {directive} named - {directiveArgumentName}, or {null} if no such argument exists. +5. Return the argument of {directive} named {directiveArgumentName}, or {null} + if no such argument exists. **Examples** From b4f2515b4fb28d3f192f0c2acab949089d0330c6 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Mon, 2 Jun 2025 10:31:22 -0500 Subject: [PATCH 40/46] Update spec/Section 3 -- Type System.md Co-authored-by: Benoit 'BoD' Lubek --- spec/Section 3 -- Type System.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index ad21ef29e..ec4b90b69 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2264,7 +2264,7 @@ ArgumentCoordinate : Name . Name ( Name : ) DirectiveCoordinate : @ Name -1. Let {directiveName} be the value of the first {Name}. +1. Let {directiveName} be the value of {Name}. 2. Return the directive in the {schema} named {directiveName}, or {null} if no such directive exists. From 8584fa343b5296ac1be1a84314dc06a21b87d9a0 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Mon, 2 Jun 2025 10:40:04 -0500 Subject: [PATCH 41/46] condense assertion --- spec/Section 3 -- Type System.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index ec4b90b69..4bcd93fe9 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2234,7 +2234,8 @@ MemberCoordinate : Name . Name 1. Let {typeName} be the value of the first {Name}. 2. Let {type} be the type in the {schema} named {typeName}. -3. Assert: {type} must exist. +3. Assert: {type} must exist, and must be an Enum, Input Object, Object or + Interface type. 4. If {type} is an Enum type: 1. Let {enumValueName} be the value of the second {Name}. 2. Return the enum value of {type} named {enumValueName}, or {null} if no @@ -2244,9 +2245,8 @@ MemberCoordinate : Name . Name 2. Return the input field of {type} named {inputFieldName}, or {null} if no such input field exists. 6. Otherwise: - 1. Assert: {type} must be an Object or Interface type. - 2. Let {fieldName} be the value of the second {Name}. - 3. Return the field of {type} named {fieldName}, or {null} if no such field + 1. Let {fieldName} be the value of the second {Name}. + 2. Return the field of {type} named {fieldName}, or {null} if no such field exists. ArgumentCoordinate : Name . Name ( Name : ) From 37c9c102a1570ac193b5ca4e4a05389f2f6be380 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Mon, 2 Jun 2025 11:51:29 -0500 Subject: [PATCH 42/46] more condensing --- spec/Section 3 -- Type System.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 4bcd93fe9..26e9a2dc8 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2253,13 +2253,12 @@ ArgumentCoordinate : Name . Name ( Name : ) 1. Let {typeName} be the value of the first {Name}. 2. Let {type} be the type in the {schema} named {typeName}. -3. Assert: {type} must exist. -4. Assert: {type} must be an Object or Interface type. -5. Let {fieldName} be the value of the second {Name}. -6. Let {field} be the field of {type} named {fieldName}. -7. Assert: {field} must exist. -8. Let {fieldArgumentName} be the value of the third {Name}. -9. Return the argument of {field} named {fieldArgumentName}, or {null} if no +3. Assert: {type} must exist, and be an Object or Interface type. +4. Let {fieldName} be the value of the second {Name}. +5. Let {field} be the field of {type} named {fieldName}. +6. Assert: {field} must exist. +7. Let {fieldArgumentName} be the value of the third {Name}. +8. Return the argument of {field} named {fieldArgumentName}, or {null} if no such argument exists. DirectiveCoordinate : @ Name From 87f6bd0c46984e7e1fdb085d56a11363a6e84b7e Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Mon, 2 Jun 2025 23:47:16 -0500 Subject: [PATCH 43/46] Update spec/Appendix B -- Grammar Summary.md Co-authored-by: Martin Bonnin --- spec/Appendix B -- Grammar Summary.md | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/spec/Appendix B -- Grammar Summary.md b/spec/Appendix B -- Grammar Summary.md index 22dab575e..945e60751 100644 --- a/spec/Appendix B -- Grammar Summary.md +++ b/spec/Appendix B -- Grammar Summary.md @@ -422,8 +422,18 @@ TypeSystemDirectiveLocation : one of SchemaCoordinate : -- Name -- Name . Name -- Name . Name ( Name : ) -- @ Name -- @ Name ( Name : ) +- TypeCoordinate +- MemberCoordinate +- ArgumentCoordinate +- DirectiveCoordinate +- DirectiveArgumentCoordinate + +TypeCoordinate : Name + +MemberCoordinate : Name . Name + +ArgumentCoordinate : Name . Name ( Name : ) + +DirectiveCoordinate : @ Name + +DirectiveArgumentCoordinate : @ Name ( Name : ) From 1cbad5dff8b222aa381aec219604d4411752d75d Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 5 Jun 2025 13:45:25 +0100 Subject: [PATCH 44/46] Use `::` syntax for enum values --- spec/Appendix B -- Grammar Summary.md | 12 +++++-- spec/Section 2 -- Language.md | 8 ++++- spec/Section 3 -- Type System.md | 48 ++++++++++++++++++--------- 3 files changed, 49 insertions(+), 19 deletions(-) diff --git a/spec/Appendix B -- Grammar Summary.md b/spec/Appendix B -- Grammar Summary.md index 945e60751..22687c6bc 100644 --- a/spec/Appendix B -- Grammar Summary.md +++ b/spec/Appendix B -- Grammar Summary.md @@ -45,12 +45,15 @@ Token :: Punctuator :: +- ColonPunctuator - DotPunctuator - OtherPunctuator +ColonPunctuator :: `:` [lookahead != {`:`}] + DotPunctuator :: `.` [lookahead != {`.`, Digit}] -OtherPunctuator :: one of ! $ & ( ) ... : = @ [ ] { | } +OtherPunctuator :: one of ! $ & ( ) ... :: = @ [ ] { | } Name :: @@ -423,17 +426,20 @@ TypeSystemDirectiveLocation : one of SchemaCoordinate : - TypeCoordinate -- MemberCoordinate +- FieldCoordinate - ArgumentCoordinate +- ValueCoordinate - DirectiveCoordinate - DirectiveArgumentCoordinate TypeCoordinate : Name -MemberCoordinate : Name . Name +FieldCoordinate : Name . Name ArgumentCoordinate : Name . Name ( Name : ) +ValueCoordinate : Name :: Name + DirectiveCoordinate : @ Name DirectiveArgumentCoordinate : @ Name ( Name : ) diff --git a/spec/Section 2 -- Language.md b/spec/Section 2 -- Language.md index 81316f0cc..9d209602c 100644 --- a/spec/Section 2 -- Language.md +++ b/spec/Section 2 -- Language.md @@ -178,17 +178,23 @@ and is {Ignored}. Punctuator :: +- ColonPunctuator - DotPunctuator - OtherPunctuator +ColonPunctuator :: `:` [lookahead != {`:`}] + DotPunctuator :: `.` [lookahead != {`.`, Digit}] -OtherPunctuator :: one of ! $ & ( ) ... : = @ [ ] { | } +OtherPunctuator :: one of ! $ & ( ) ... :: = @ [ ] { | } GraphQL documents include punctuation in order to describe structure. GraphQL is a data description language and not a programming language, therefore GraphQL lacks the punctuation often used to describe mathematical expressions. +The {`:`} punctuator must not be followed by a {`:`}. This ensures that the +source {"::"} can only be interpreted as a single {`::`} and not two {`:`}. + The {`.`} punctuator must not be followed by a {`.`} or {Digit}. This ensures that the source {"..."} can only be interpreted as a single {`...`} and not three {`.`}. It also avoids any potential ambiguity with {FloatValue}. As an diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 26e9a2dc8..e36b5d929 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2174,17 +2174,20 @@ scalar UUID @specifiedBy(url: "https://tools.ietf.org/html/rfc4122") SchemaCoordinate : - TypeCoordinate -- MemberCoordinate +- FieldCoordinate - ArgumentCoordinate +- ValueCoordinate - DirectiveCoordinate - DirectiveArgumentCoordinate TypeCoordinate : Name -MemberCoordinate : Name . Name +FieldCoordinate : Name . Name ArgumentCoordinate : Name . Name ( Name : ) +ValueCoordinate : Name :: Name + DirectiveCoordinate : @ Name DirectiveArgumentCoordinate : @ Name ( Name : ) @@ -2195,6 +2198,16 @@ _schema element_ within a GraphQL Schema. :: A _schema element_ can be a named type, a field, an input field, an enum value, a field argument, a directive, or a directive argument. +:: The _containing element_ of a _schema element_ is the schema element with one +fewer {Name} token that syntactically contains it. For example: + +- The containing element of an {ArgumentCoordinate} or + {DirectiveArgumentCoordinate} is the corresponding {FieldCoordinate} or + {DirectiveCoordinate} respectively. +- The containing element of a {FieldCoordinate} or {ValueCoordinate} is its + containing {TypeCoordinate}. +- {TypeCoordinate} and {DirectiveCoordinate} have no containing element. + A _schema coordinate_ is always unique. Each _schema element_ can be referenced by exactly one possible schema coordinate. @@ -2220,9 +2233,9 @@ production. To refer to a _schema element_, a _schema coordinate_ must be interpreted in the context of a GraphQL {schema}. -If the _schema element_ cannot be found, the resolve function will not yield a -value (without raising an error). However, an error will be raised if any -non-leaf nodes within a _schema coordinate_ cannot be found in the {schema}. +If the _schema element_ cannot be found, and either it has no _containing +element_ or its _containing element_ exists and is of the expected type, the +resolve function returns {null}. Otherwise, an error is raised. TypeCoordinate : Name @@ -2230,21 +2243,17 @@ TypeCoordinate : Name 2. Return the type in the {schema} named {typeName}, or {null} if no such type exists. -MemberCoordinate : Name . Name +FieldCoordinate : Name . Name 1. Let {typeName} be the value of the first {Name}. 2. Let {type} be the type in the {schema} named {typeName}. -3. Assert: {type} must exist, and must be an Enum, Input Object, Object or - Interface type. -4. If {type} is an Enum type: - 1. Let {enumValueName} be the value of the second {Name}. - 2. Return the enum value of {type} named {enumValueName}, or {null} if no - such value exists. -5. Otherwise, if {type} is an Input Object type: +3. Assert: {type} must exist, and must be an Input Object, Object or Interface + type. +4. If {type} is an Input Object type: 1. Let {inputFieldName} be the value of the second {Name}. 2. Return the input field of {type} named {inputFieldName}, or {null} if no such input field exists. -6. Otherwise: +5. Otherwise: 1. Let {fieldName} be the value of the second {Name}. 2. Return the field of {type} named {fieldName}, or {null} if no such field exists. @@ -2261,6 +2270,15 @@ ArgumentCoordinate : Name . Name ( Name : ) 8. Return the argument of {field} named {fieldArgumentName}, or {null} if no such argument exists. +ValueCoordinate : Name :: Name + +1. Let {typeName} be the value of the first {Name}. +2. Let {type} be the type in the {schema} named {typeName}. +3. Assert: {type} must exist, and must be an Enum type. +4. Let {enumValueName} be the value of the second {Name}. +5. Return the enum value of {type} named {enumValueName}, or {null} if no such + value exists. + DirectiveCoordinate : @ Name 1. Let {directiveName} be the value of {Name}. @@ -2283,8 +2301,8 @@ DirectiveArgumentCoordinate : @ Name ( Name : ) | Named Type | `Business` | `Business` type | | Field | `Business.name` | `name` field on the `Business` type | | Input Field | `SearchCriteria.filter` | `filter` input field on the `SearchCriteria` input object type | -| Enum Value | `SearchFilter.OPEN_NOW` | `OPEN_NOW` value of the `SearchFilter` enum | | Field Argument | `Query.searchBusiness(criteria:)` | `criteria` argument on the `searchBusiness` field on the `Query` type | +| Enum Value | `SearchFilter::OPEN_NOW` | `OPEN_NOW` value of the `SearchFilter` enum | | Directive | `@private` | `@private` directive | | Directive Argument | `@private(scope:)` | `scope` argument on the `@private` directive | From 7b754896b8019078ed8e5af607acc5792779f582 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Fri, 6 Jun 2025 12:15:17 -0500 Subject: [PATCH 45/46] Revert "Use `::` syntax for enum values" This reverts commit 1cbad5dff8b222aa381aec219604d4411752d75d. --- spec/Appendix B -- Grammar Summary.md | 12 ++----- spec/Section 2 -- Language.md | 8 +---- spec/Section 3 -- Type System.md | 48 +++++++++------------------ 3 files changed, 19 insertions(+), 49 deletions(-) diff --git a/spec/Appendix B -- Grammar Summary.md b/spec/Appendix B -- Grammar Summary.md index 22687c6bc..945e60751 100644 --- a/spec/Appendix B -- Grammar Summary.md +++ b/spec/Appendix B -- Grammar Summary.md @@ -45,15 +45,12 @@ Token :: Punctuator :: -- ColonPunctuator - DotPunctuator - OtherPunctuator -ColonPunctuator :: `:` [lookahead != {`:`}] - DotPunctuator :: `.` [lookahead != {`.`, Digit}] -OtherPunctuator :: one of ! $ & ( ) ... :: = @ [ ] { | } +OtherPunctuator :: one of ! $ & ( ) ... : = @ [ ] { | } Name :: @@ -426,20 +423,17 @@ TypeSystemDirectiveLocation : one of SchemaCoordinate : - TypeCoordinate -- FieldCoordinate +- MemberCoordinate - ArgumentCoordinate -- ValueCoordinate - DirectiveCoordinate - DirectiveArgumentCoordinate TypeCoordinate : Name -FieldCoordinate : Name . Name +MemberCoordinate : Name . Name ArgumentCoordinate : Name . Name ( Name : ) -ValueCoordinate : Name :: Name - DirectiveCoordinate : @ Name DirectiveArgumentCoordinate : @ Name ( Name : ) diff --git a/spec/Section 2 -- Language.md b/spec/Section 2 -- Language.md index 9d209602c..81316f0cc 100644 --- a/spec/Section 2 -- Language.md +++ b/spec/Section 2 -- Language.md @@ -178,23 +178,17 @@ and is {Ignored}. Punctuator :: -- ColonPunctuator - DotPunctuator - OtherPunctuator -ColonPunctuator :: `:` [lookahead != {`:`}] - DotPunctuator :: `.` [lookahead != {`.`, Digit}] -OtherPunctuator :: one of ! $ & ( ) ... :: = @ [ ] { | } +OtherPunctuator :: one of ! $ & ( ) ... : = @ [ ] { | } GraphQL documents include punctuation in order to describe structure. GraphQL is a data description language and not a programming language, therefore GraphQL lacks the punctuation often used to describe mathematical expressions. -The {`:`} punctuator must not be followed by a {`:`}. This ensures that the -source {"::"} can only be interpreted as a single {`::`} and not two {`:`}. - The {`.`} punctuator must not be followed by a {`.`} or {Digit}. This ensures that the source {"..."} can only be interpreted as a single {`...`} and not three {`.`}. It also avoids any potential ambiguity with {FloatValue}. As an diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index e36b5d929..26e9a2dc8 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2174,20 +2174,17 @@ scalar UUID @specifiedBy(url: "https://tools.ietf.org/html/rfc4122") SchemaCoordinate : - TypeCoordinate -- FieldCoordinate +- MemberCoordinate - ArgumentCoordinate -- ValueCoordinate - DirectiveCoordinate - DirectiveArgumentCoordinate TypeCoordinate : Name -FieldCoordinate : Name . Name +MemberCoordinate : Name . Name ArgumentCoordinate : Name . Name ( Name : ) -ValueCoordinate : Name :: Name - DirectiveCoordinate : @ Name DirectiveArgumentCoordinate : @ Name ( Name : ) @@ -2198,16 +2195,6 @@ _schema element_ within a GraphQL Schema. :: A _schema element_ can be a named type, a field, an input field, an enum value, a field argument, a directive, or a directive argument. -:: The _containing element_ of a _schema element_ is the schema element with one -fewer {Name} token that syntactically contains it. For example: - -- The containing element of an {ArgumentCoordinate} or - {DirectiveArgumentCoordinate} is the corresponding {FieldCoordinate} or - {DirectiveCoordinate} respectively. -- The containing element of a {FieldCoordinate} or {ValueCoordinate} is its - containing {TypeCoordinate}. -- {TypeCoordinate} and {DirectiveCoordinate} have no containing element. - A _schema coordinate_ is always unique. Each _schema element_ can be referenced by exactly one possible schema coordinate. @@ -2233,9 +2220,9 @@ production. To refer to a _schema element_, a _schema coordinate_ must be interpreted in the context of a GraphQL {schema}. -If the _schema element_ cannot be found, and either it has no _containing -element_ or its _containing element_ exists and is of the expected type, the -resolve function returns {null}. Otherwise, an error is raised. +If the _schema element_ cannot be found, the resolve function will not yield a +value (without raising an error). However, an error will be raised if any +non-leaf nodes within a _schema coordinate_ cannot be found in the {schema}. TypeCoordinate : Name @@ -2243,17 +2230,21 @@ TypeCoordinate : Name 2. Return the type in the {schema} named {typeName}, or {null} if no such type exists. -FieldCoordinate : Name . Name +MemberCoordinate : Name . Name 1. Let {typeName} be the value of the first {Name}. 2. Let {type} be the type in the {schema} named {typeName}. -3. Assert: {type} must exist, and must be an Input Object, Object or Interface - type. -4. If {type} is an Input Object type: +3. Assert: {type} must exist, and must be an Enum, Input Object, Object or + Interface type. +4. If {type} is an Enum type: + 1. Let {enumValueName} be the value of the second {Name}. + 2. Return the enum value of {type} named {enumValueName}, or {null} if no + such value exists. +5. Otherwise, if {type} is an Input Object type: 1. Let {inputFieldName} be the value of the second {Name}. 2. Return the input field of {type} named {inputFieldName}, or {null} if no such input field exists. -5. Otherwise: +6. Otherwise: 1. Let {fieldName} be the value of the second {Name}. 2. Return the field of {type} named {fieldName}, or {null} if no such field exists. @@ -2270,15 +2261,6 @@ ArgumentCoordinate : Name . Name ( Name : ) 8. Return the argument of {field} named {fieldArgumentName}, or {null} if no such argument exists. -ValueCoordinate : Name :: Name - -1. Let {typeName} be the value of the first {Name}. -2. Let {type} be the type in the {schema} named {typeName}. -3. Assert: {type} must exist, and must be an Enum type. -4. Let {enumValueName} be the value of the second {Name}. -5. Return the enum value of {type} named {enumValueName}, or {null} if no such - value exists. - DirectiveCoordinate : @ Name 1. Let {directiveName} be the value of {Name}. @@ -2301,8 +2283,8 @@ DirectiveArgumentCoordinate : @ Name ( Name : ) | Named Type | `Business` | `Business` type | | Field | `Business.name` | `name` field on the `Business` type | | Input Field | `SearchCriteria.filter` | `filter` input field on the `SearchCriteria` input object type | +| Enum Value | `SearchFilter.OPEN_NOW` | `OPEN_NOW` value of the `SearchFilter` enum | | Field Argument | `Query.searchBusiness(criteria:)` | `criteria` argument on the `searchBusiness` field on the `Query` type | -| Enum Value | `SearchFilter::OPEN_NOW` | `OPEN_NOW` value of the `SearchFilter` enum | | Directive | `@private` | `@private` directive | | Directive Argument | `@private(scope:)` | `scope` argument on the `@private` directive | From be6938c915cd7d81d444b717fcd27e9ea487800f Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Fri, 6 Jun 2025 15:31:07 -0500 Subject: [PATCH 46/46] revert back to MemberCoordinates --- spec/Section 3 -- Type System.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 26e9a2dc8..b85993e04 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2195,14 +2195,21 @@ _schema element_ within a GraphQL Schema. :: A _schema element_ can be a named type, a field, an input field, an enum value, a field argument, a directive, or a directive argument. +:: The _containing element_ of a _schema element_ is the schema element with one +fewer {Name} token that syntactically contains it. Specifically: + +- {MemberCoordinate} has a {TypeCoordinate} containing element. +- {ArgumentCoordinate} has a {MemberCoordinate} containing element. +- {DirectiveArgumentCoordinate} has a {DirectiveCoordinate} containing element. +- {TypeCoordinate} and {DirectiveCoordinate} have no containing element. + A _schema coordinate_ is always unique. Each _schema element_ can be referenced by exactly one possible schema coordinate. A _schema coordinate_ may refer to either a defined or built-in _schema element_. For example, `String` and `@deprecated(reason:)` are both valid schema -coordinates which refer to built-in schema elements. However it must not refer -to a meta-field. For example, `Business.__typename` is _not_ a valid schema -coordinate. +coordinates which refer to built-in schema elements. Meta-fields may also be +referenced. For example, `Business.__typename` is a valid schema coordinate. Note: Union members are not valid _schema coordinate_ as they reference existing types in the schema. This preserves the uniqueness property of a _schema