Skip to content

Commit 1e29b8a

Browse files
magicmarkbenjieleebyronmartinbonninBoD
authored
Schema Coordinates (#794)
* Add Schema Coordinates RFC * Update schema coordinates spec edit - Make examples table - Tweak the grammar definition * implement PR suggestions - move schema coordinates to section 3.3.3 - add lee's grammar suggestion * Tweak example table wording * Apply suggestions from code review Co-authored-by: Benjie Gillam <[email protected]> * enumName -> enumValueName * - Add PR feedback - remove extraneous examples - tighten up wording * Update Section 3 -- Type System.md * Editorial on grammar and semantics * Move section * Simplify examples * standalone https://brians.wsu.edu/2016/05/31/standalone-stand-alone/ Co-authored-by: Benjie Gillam <[email protected]> * update numbers * clarify element * Update Punctuator grammar * specify schema element * fix example * clarify metafields * Better Punctator * Minor algo variable name refinements * whitespace fix * add note about union members * prettier * formatting * Update spec/Section 3 -- Type System.md Co-authored-by: Martin Bonnin <[email protected]> * Update spec/Section 3 -- Type System.md Co-authored-by: Martin Bonnin <[email protected]> * Run prettier * add spec updates * Add back assertion * assert that ... -> assert ... * consistent periods * consistent exists/must exist * void -> null * remove note prefix for error throwing note * Various stylistic fixes * Update spec/Section 3 -- Type System.md Co-authored-by: Benoit 'BoD' Lubek <[email protected]> * Update spec/Section 3 -- Type System.md Co-authored-by: Benoit 'BoD' Lubek <[email protected]> * Apply benjie's suggestions from code review Co-authored-by: Benjie <[email protected]> * split out SchemaCoordinate definition * Update spec/Section 3 -- Type System.md Co-authored-by: Benoit 'BoD' Lubek <[email protected]> * condense assertion * more condensing * Update spec/Appendix B -- Grammar Summary.md Co-authored-by: Martin Bonnin <[email protected]> * Use `::` syntax for enum values * Revert "Use `::` syntax for enum values" This reverts commit 1cbad5d. * revert back to MemberCoordinates * ", or {null} if no such field exists." -> "if it exists." * add non-metafield clarification * Spell check * Add note about meta-fields * "in the {schema}" -> "in {schema}" for consistency with the spec * Apply suggestions from code review Co-authored-by: Benjie <[email protected]> * formatting * Update spec/Section 3 -- Type System.md Co-authored-by: Benjie <[email protected]> * Update Section 2 -- Language.md * Revert "Update Section 2 -- Language.md" This reverts commit f4eec91. * restrict schema coordinates to a unique grammar * format * Apply suggestions from code review Co-authored-by: Benjie <[email protected]> * move and minor edits * tighten notes * update resolution grammar * fix table style --------- Co-authored-by: Benjie Gillam <[email protected]> Co-authored-by: Lee Byron <[email protected]> Co-authored-by: Lee Byron <[email protected]> Co-authored-by: Martin Bonnin <[email protected]> Co-authored-by: Benoit 'BoD' Lubek <[email protected]>
1 parent bc4ddea commit 1e29b8a

File tree

2 files changed

+202
-0
lines changed

2 files changed

+202
-0
lines changed

spec/Appendix B -- Grammar Summary.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,3 +413,32 @@ TypeSystemDirectiveLocation : one of
413413
- `ENUM_VALUE`
414414
- `INPUT_OBJECT`
415415
- `INPUT_FIELD_DEFINITION`
416+
417+
## Schema Coordinate Syntax
418+
419+
Note: Schema coordinates must not contain {Ignored}.
420+
421+
SchemaCoordinateToken ::
422+
423+
- SchemaCoordinatePunctuator
424+
- Name
425+
426+
SchemaCoordinatePunctuator :: one of ( ) . : @
427+
428+
SchemaCoordinate ::
429+
430+
- TypeCoordinate
431+
- MemberCoordinate
432+
- ArgumentCoordinate
433+
- DirectiveCoordinate
434+
- DirectiveArgumentCoordinate
435+
436+
TypeCoordinate :: Name
437+
438+
MemberCoordinate :: Name . Name
439+
440+
ArgumentCoordinate :: Name . Name ( Name : )
441+
442+
DirectiveCoordinate :: @ Name
443+
444+
DirectiveArgumentCoordinate :: @ Name ( Name : )

spec/Section 2 -- Language.md

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,3 +1377,176 @@ type Person
13771377
name: String
13781378
}
13791379
```
1380+
1381+
## Schema Coordinates
1382+
1383+
SchemaCoordinate ::
1384+
1385+
- TypeCoordinate
1386+
- MemberCoordinate
1387+
- ArgumentCoordinate
1388+
- DirectiveCoordinate
1389+
- DirectiveArgumentCoordinate
1390+
1391+
TypeCoordinate :: Name
1392+
1393+
MemberCoordinate :: Name . Name
1394+
1395+
ArgumentCoordinate :: Name . Name ( Name : )
1396+
1397+
DirectiveCoordinate :: @ Name
1398+
1399+
DirectiveArgumentCoordinate :: @ Name ( Name : )
1400+
1401+
:: A _schema coordinate_ is a human readable string that uniquely identifies a
1402+
_schema element_ within a GraphQL Schema, intended to be used by tools to
1403+
reference types, fields, and other _schema element_. Examples include:
1404+
references within documentation to refer to types and fields in a schema, a
1405+
lookup key that can be used in logging tools to track how often particular
1406+
fields are queried in production.
1407+
1408+
:: A _schema element_ can be a named type, a field, an input field, an enum
1409+
value, a field argument, a directive, or a directive argument defined within a
1410+
schema (including built-in types and directives).
1411+
1412+
Note: Meta-fields are not defined within a schema, and thus are not _schema
1413+
element_. By extension, an introspection type is not a _schema element_.
1414+
1415+
:: The _containing element_ of a _schema element_ is the schema element with one
1416+
fewer {Name} token that syntactically contains it. Specifically:
1417+
1418+
- The containing element of an {ArgumentCoordinate} is a {MemberCoordinate}.
1419+
- The containing element of a {MemberCoordinate} is a {TypeCoordinate}.
1420+
- The containing element of a {DirectiveArgumentCoordinate} is a
1421+
{DirectiveCoordinate}.
1422+
- {TypeCoordinate} and {DirectiveCoordinate} have no containing element.
1423+
1424+
A _schema coordinate_ is always unique. Each _schema element_ can be referenced
1425+
by exactly one possible schema coordinate.
1426+
1427+
A _schema coordinate_ may refer to either a defined or built-in _schema
1428+
element_. For example, `String` and `@deprecated(reason:)` are both valid schema
1429+
coordinates which refer to built-in schema elements.
1430+
1431+
Note: A union member references a type in the schema. A type in the schema is
1432+
identified by a {TypeCoordinate}. There is no schema coordinate which indicates
1433+
a union member; this preserves the uniqueness property of a _schema coordinate_
1434+
as stated above.
1435+
1436+
**Parsing a Schema Coordinate**
1437+
1438+
SchemaCoordinateToken ::
1439+
1440+
- SchemaCoordinatePunctuator
1441+
- Name
1442+
1443+
SchemaCoordinatePunctuator :: one of ( ) . : @
1444+
1445+
A {SchemaCoordinate} is a self-contained grammar with its own set of lexical
1446+
tokens, it is not contained within a {Document}. The source text of a
1447+
SchemaCoordinate must be a sequence of {SourceCharacter}.
1448+
1449+
Unlike other [GraphQL documents](#sec-Language), {SchemaCoordinate} must not
1450+
contain {Whitespace} or other {Ignored} grammars within the character sequence.
1451+
This ensures that every schema coordinates has a single unambiguous and unique
1452+
lexical form.
1453+
1454+
**Resolving a Schema Coordinate**
1455+
1456+
To refer to a _schema element_, a _schema coordinate_ must be interpreted in the
1457+
context of a GraphQL {schema}.
1458+
1459+
If the _schema element_ cannot be found, the resolve function will not yield a
1460+
value (without raising an error). However, an error will be raised if any
1461+
non-leaf nodes within a _schema coordinate_ cannot be found in the {schema}.
1462+
1463+
Note: Although it is syntactically possible to describe a meta-field or element
1464+
of the introspection schema with a schema coordinate (e.g. `Business.__typename`
1465+
or `__Type.fields(includeDeprecated:)`), they are not _schema element_ and
1466+
therefore resolving such coordinates does not have a defined behavior.
1467+
1468+
TypeCoordinate :: Name
1469+
1470+
1. Let {typeName} be the value of {Name}.
1471+
2. Return the type in {schema} named {typeName} if it exists.
1472+
1473+
MemberCoordinate :: Name . Name
1474+
1475+
1. Let {typeName} be the value of the first {Name}.
1476+
2. Let {type} be the type in {schema} named {typeName}.
1477+
3. Assert: {type} must exist, and must be an Enum, Input Object, Object or
1478+
Interface type.
1479+
4. If {type} is an Enum type:
1480+
1. Let {enumValueName} be the value of the second {Name}.
1481+
2. Return the enum value of {type} named {enumValueName} if it exists.
1482+
5. Otherwise, if {type} is an Input Object type:
1483+
1. Let {inputFieldName} be the value of the second {Name}.
1484+
2. Return the input field of {type} named {inputFieldName} if it exists.
1485+
6. Otherwise:
1486+
1. Let {fieldName} be the value of the second {Name}.
1487+
2. Return the field of {type} named {fieldName} if it exists.
1488+
1489+
ArgumentCoordinate :: Name . Name ( Name : )
1490+
1491+
1. Let {typeName} be the value of the first {Name}.
1492+
2. Let {type} be the type in {schema} named {typeName}.
1493+
3. Assert: {type} must exist, and be an Object or Interface type.
1494+
4. Let {fieldName} be the value of the second {Name}.
1495+
5. Let {field} be the field of {type} named {fieldName}.
1496+
6. Assert: {field} must exist.
1497+
7. Let {fieldArgumentName} be the value of the third {Name}.
1498+
8. Return the argument of {field} named {fieldArgumentName} if it exists.
1499+
1500+
DirectiveCoordinate :: @ Name
1501+
1502+
1. Let {directiveName} be the value of {Name}.
1503+
2. Return the directive in {schema} named {directiveName} if it exists.
1504+
1505+
DirectiveArgumentCoordinate :: @ Name ( Name : )
1506+
1507+
1. Let {directiveName} be the value of the first {Name}.
1508+
2. Let {directive} be the directive in {schema} named {directiveName}.
1509+
3. Assert: {directive} must exist.
1510+
4. Let {directiveArgumentName} be the value of the second {Name}.
1511+
5. Return the argument of {directive} named {directiveArgumentName} if it
1512+
exists.
1513+
1514+
**Examples**
1515+
1516+
| Element Kind | Schema Coordinate | Schema Element |
1517+
| ------------------ | --------------------------------- | --------------------------------------------------------------------- |
1518+
| Named Type | `Business` | `Business` type |
1519+
| Field | `Business.name` | `name` field on the `Business` type |
1520+
| Input Field | `SearchCriteria.filter` | `filter` input field on the `SearchCriteria` input object type |
1521+
| Enum Value | `SearchFilter.OPEN_NOW` | `OPEN_NOW` value of the `SearchFilter` enum |
1522+
| Field Argument | `Query.searchBusiness(criteria:)` | `criteria` argument on the `searchBusiness` field on the `Query` type |
1523+
| Directive | `@private` | `@private` directive |
1524+
| Directive Argument | `@private(scope:)` | `scope` argument on the `@private` directive |
1525+
1526+
The table above shows an example of a _schema coordinate_ for every kind of
1527+
_schema element_ based on the schema below.
1528+
1529+
```graphql
1530+
type Query {
1531+
searchBusiness(criteria: SearchCriteria!): [Business]
1532+
}
1533+
1534+
input SearchCriteria {
1535+
name: String
1536+
filter: SearchFilter
1537+
}
1538+
1539+
enum SearchFilter {
1540+
OPEN_NOW
1541+
DELIVERS_TAKEOUT
1542+
VEGETARIAN_MENU
1543+
}
1544+
1545+
type Business {
1546+
id: ID
1547+
name: String
1548+
email: String @private(scope: "loggedIn")
1549+
}
1550+
1551+
directive @private(scope: String!) on FIELD_DEFINITION
1552+
```

0 commit comments

Comments
 (0)