Skip to content

Schema Coordinates #794

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 48 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
38616cc
Add Schema Coordinates RFC
magicmark Sep 17, 2020
45fb46c
Update schema coordinates spec edit
magicmark Nov 18, 2020
eabdaff
implement PR suggestions
magicmark Nov 21, 2020
f994f99
Tweak example table wording
magicmark Nov 22, 2020
17002d4
Apply suggestions from code review
magicmark Nov 23, 2020
6456c5f
enumName -> enumValueName
magicmark Nov 28, 2020
4905977
- Add PR feedback
magicmark Jan 4, 2021
8be29ca
Update Section 3 -- Type System.md
magicmark Jan 7, 2021
568d26f
Editorial on grammar and semantics
leebyron Apr 13, 2021
b8f3f47
Move section
leebyron Apr 13, 2021
8580162
Simplify examples
leebyron Apr 14, 2021
87a38e2
standalone
leebyron Apr 15, 2021
75c48ba
update numbers
leebyron Apr 16, 2021
148d073
clarify element
leebyron Apr 16, 2021
c43f4aa
Update Punctuator grammar
leebyron Apr 16, 2021
bb896cf
specify schema element
leebyron Apr 16, 2021
e5a2092
fix example
leebyron Apr 16, 2021
b65eb31
clarify metafields
leebyron Apr 16, 2021
c16a28b
Better Punctator
leebyron Apr 16, 2021
93bd2c6
Minor algo variable name refinements
leebyron Apr 22, 2021
b2e42e8
whitespace fix
magicmark Dec 10, 2024
4ce2d48
add note about union members
magicmark Dec 10, 2024
2d60b33
prettier
magicmark Dec 10, 2024
d61cdc3
formatting
magicmark Dec 10, 2024
caed065
Update spec/Section 3 -- Type System.md
magicmark Jan 2, 2025
07b3bbd
Update spec/Section 3 -- Type System.md
magicmark Jan 2, 2025
a3383ee
Merge branch 'main' into schema_coordinates_spec_edit
benjie May 15, 2025
258d841
Run prettier
benjie May 16, 2025
8a97138
add spec updates
magicmark Jun 2, 2025
c8a2cfe
Add back assertion
magicmark Jun 2, 2025
a96836a
assert that ... -> assert ...
magicmark Jun 2, 2025
3effd4a
consistent periods
magicmark Jun 2, 2025
9feceb2
consistent exists/must exist
magicmark Jun 2, 2025
11b9e96
void -> null
magicmark Jun 2, 2025
10742dd
remove note prefix for error throwing note
magicmark Jun 2, 2025
4b9f37a
Various stylistic fixes
benjie Jun 2, 2025
3555f57
Update spec/Section 3 -- Type System.md
magicmark Jun 2, 2025
a52e312
Update spec/Section 3 -- Type System.md
magicmark Jun 2, 2025
dc1374d
Apply benjie's suggestions from code review
magicmark Jun 2, 2025
8c01802
split out SchemaCoordinate definition
magicmark Jun 2, 2025
b4f2515
Update spec/Section 3 -- Type System.md
magicmark Jun 2, 2025
8584fa3
condense assertion
magicmark Jun 2, 2025
37c9c10
more condensing
magicmark Jun 2, 2025
87f6bd0
Update spec/Appendix B -- Grammar Summary.md
magicmark Jun 3, 2025
1cbad5d
Use `::` syntax for enum values
benjie Jun 5, 2025
ff1ccb4
Merge pull request #1 from graphql/coloncolon
magicmark Jun 5, 2025
7b75489
Revert "Use `::` syntax for enum values"
magicmark Jun 6, 2025
be6938c
revert back to MemberCoordinates
magicmark Jun 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion spec/Appendix B -- Grammar Summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,14 @@ Token ::
- FloatValue
- StringValue

Punctuator :: one of ! $ & ( ) ... : = @ [ ] { | }
Punctuator ::

- DotPunctuator
- OtherPunctuator

DotPunctuator :: `.` [lookahead != {`.`, Digit}]

OtherPunctuator :: one of ! $ & ( ) ... : = @ [ ] { | }

Name ::

Expand Down Expand Up @@ -412,3 +419,21 @@ TypeSystemDirectiveLocation : one of
- `ENUM_VALUE`
- `INPUT_OBJECT`
- `INPUT_FIELD_DEFINITION`

SchemaCoordinate :

- TypeCoordinate
- MemberCoordinate
- ArgumentCoordinate
- DirectiveCoordinate
- DirectiveArgumentCoordinate

TypeCoordinate : Name

MemberCoordinate : Name . Name

ArgumentCoordinate : Name . Name ( Name : )

DirectiveCoordinate : @ Name

DirectiveArgumentCoordinate : @ Name ( Name : )
15 changes: 14 additions & 1 deletion spec/Section 2 -- Language.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,25 @@ and is {Ignored}.

### Punctuators

Punctuator :: one of ! $ & ( ) ... : = @ [ ] { | }
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 ::
Expand Down
154 changes: 154 additions & 0 deletions spec/Section 3 -- Type System.md
Original file line number Diff line number Diff line change
Expand Up @@ -2168,3 +2168,157 @@ to the relevant IETF specification.
```graphql example
scalar UUID @specifiedBy(url: "https://tools.ietf.org/html/rfc4122")
```

## Schema Coordinates

SchemaCoordinate :

- 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.

:: 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. 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
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_. 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.

**Resolving a Schema Coordinate**

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}.

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.

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 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.
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.

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, 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

1. Let {directiveName} be the value of {Name}.
2. Return the directive in the {schema} named {directiveName}, or {null} if no
such directive exists.

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.

**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.

```graphql
type Query {
searchBusiness(criteria: SearchCriteria!): [Business]
}

input SearchCriteria {
name: String
filter: SearchFilter
}

enum SearchFilter {
OPEN_NOW
DELIVERS_TAKEOUT
VEGETARIAN_MENU
}

type Business {
id: ID
name: String
email: String @private(scope: "loggedIn")
}

directive @private(scope: String!) on FIELD_DEFINITION
```