From 72438bf7889cce6930242044ab68311e216ff2c8 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Thu, 17 Sep 2020 02:17:07 -0700 Subject: [PATCH 01/16] Add Schema Coordinates RFC --- rfcs/SchemaCoordinates.md | 372 +++++++++++++++++++++++ spec/Appendix C -- Schema Coordinates.md | 168 ++++++++++ spec/GraphQL.md | 2 + 3 files changed, 542 insertions(+) create mode 100644 rfcs/SchemaCoordinates.md create mode 100644 spec/Appendix C -- Schema Coordinates.md diff --git a/rfcs/SchemaCoordinates.md b/rfcs/SchemaCoordinates.md new file mode 100644 index 000000000..4181cf707 --- /dev/null +++ b/rfcs/SchemaCoordinates.md @@ -0,0 +1,372 @@ +# RFC: Schema Coordinates + +**Proposed by:** [Mark Larah](https://twitter.com/mark_larah) - Yelp + +This RFC proposes formalizing "Schema Coordinates" - a human readable syntax to +uniquely identify a type, field, or field argument defined in a GraphQL Schema. + +This should be listed as a non-normative note in the GraphQL specification to +serve as an official reference for use by third party tooling. + +## 📜 Problem Statement + +Third party GraphQL tooling and libraries may wish to refer to a field, or set of +fields in a schema. Use cases include documentation, metrics and logging +libraries. + +![](https://i.fluffy.cc/5Cz9cpwLVsH1FsSF9VPVLwXvwrGpNh7q.png) + +_(Example shown from GraphiQL's documentation search tab)_ + +There already exists a convention used by some third party libraries for writing +out fields in a unique way for such purposes. However, there is no formal +specification or name for this convention. + +### Use cases + +1. A GraphQL server wants to **log how often each field in the schema is + requested**. This may be implemented by incrementing a counter by the name of + the schema coordinate for each field executed in a request. + + _Existing implementations: Yelp (internal), Facebook (internal)_ + +1. GraphiQL and other playgrounds / documentation sites want to show a list of + **search results** when a user searches for a type or field name. We can + display a list of schema coordinates that match the search term. A schema + coordinate can also be used in the hyperlink to form a permalink for + documentation for a particular field. + + _Existing implementations: GraphiQL, Apollo Studio (see "Prior Art")_ + +1. A developer may want to perform **analytics** on all known + [persisted queries][apq] - e.g. what are the most commonly used fields across + all documents. Schema coordinates may be used as the index/lookup keys when + storing this information in the database. + + _Existing implementations: Yelp (internal)_ + + [apq]: https://www.apollographql.com/docs/apollo-server/performance/apq/ + +1. A **GitHub bot** may want to warn developers in a Pull Request comment + whenever the schema diff contains a breaking change. Schema selectors can be + used to provide a list of which fields were broken. + + _Existing implementations: GraphQL Inspector (see "Prior Art")_ + +1. **GraphQL IDEs** (e.g. GraphiQL, GraphQL Playground, Apollo Studio) may wish + to display the schema definition type of a node in a query when hovering over + it. + +
+ Example + ![](https://i.fluffy.cc/g78sJCjCJ0MsbNPhvgPXP46Kh9knBCKF.png) +
+ + Schema coordinates can be used to form the left hand side of this popover. + +_Existing implementations: Apollo Studio (see "Prior Art")_ + +## 🚫 What this RFC does _not_ propose + +- This does not cover "selectors" or "wildcard" syntax - e.g. `User.*`. _(See + alternatives considered.)_ +- There are **no proposed GraphQL language/syntax changes** +- There are **no proposed GraphQL runtime changes** +- [Schema coordinate non-goals](#-syntax-non-goals) + +## ✨ Worked Examples + +For example, consider the following schema: + +```graphql +type Person { + name: String +} + +type Business { + name: String + owner: Person +} + +type Query { + searchBusinesses(name: String): [Business] +} +``` + +We can write the following list of Schema Coordinates: + +- `Person` uniquely identifies the the "Person" type +- `Business` uniquely identifies the the "Business" type +- `Person.name` uniquely identifies the "name" field on the "Person" type +- `Business.name` uniquely identifies the "name" field on the "Business" + type +- `Business.owner` uniquely identifies the "owner" field on the "Business" type +- `Query.searchBusinesses` uniquely identifies the "searchBusinesses" field on + the "Query" type +- `Query.searchBusinesses(name)` uniquely identifies the "name" argument on the + "searchBusinesses" field on the "Query" type + +This RFC standardizes how we write coordinates GraphQL Schema members as above. + +## 🎨 Prior art + +- The name "schema coordinates" is inspired from [GraphQL Java](https://github.com/graphql-java/graphql-java) + (4.3k stars), where "field coordinates" are already used in a similar way as + described in this RFC. + + - [GitHub comment](https://github.com/graphql/graphql-spec/issues/735#issuecomment-646979049) + - [Implementation](https://github.com/graphql-java/graphql-java/blob/2acb557474ca73/src/main/java/graphql/schema/FieldCoordinates.java) + +- GraphiQL displays schema coordinates in its documentation search tab: + + ![](https://i.fluffy.cc/5Cz9cpwLVsH1FsSF9VPVLwXvwrGpNh7q.png) + +- [GraphQL Inspector](https://github.com/kamilkisiela/graphql-inspector) (840 + stars) shows schema coordinates in its output: + + ![](https://i.imgur.com/HAf18rz.png) + +- [Apollo Studio](https://www.apollographql.com/docs/studio/) shows schema + coordinates when hovering over fields in a query: + + ![](https://i.fluffy.cc/g78sJCjCJ0MsbNPhvgPXP46Kh9knBCKF.png) + +## 🥣 Document -> Schema Coordinate serialization + +Use cases 3 and 5 above imply that a mapping from GraphQL query nodes to schema +coordinates is performed. + +For example, consider the following schema: + +```graphql +type Person { + name: String +} + +type Business { + name: String + owner: Person +} + +type Query { + searchBusiness(name: String): [Business] +} +``` + +And the following query: + +```graphql +query { + searchBusinesses(name: "El Greco Deli") { + name + owner { + name + } + } +} +``` + +From the query above, we may calculate the following list of schema coordinates: + +- `Query.searchBusinesses` +- `Business.name` +- `Business.owner` +- `Person.name` + +_`Query.searchBusinesses(name)` is also a valid member of the output set. The +serialization algorithm may optionally choose to output all permutations of field +arguments used, should this be specified._ + +A library has been written to demonstrate this mapping: https://github.com/sharkcore/extract-schema-coordinates. + +## 🗳️ Alternatives considered + +### Naming + +- **"Schema Selectors"** + + "Selectors" is a term used in [HTML](https://www.w3.org/TR/selectors-api/) and + [CSS](https://drafts.csswg.org/selectors-4/) to _select_ parts of an HTML + document. + + This would be a compelling, familiar choice - however, we've decided to not + support wildcard expansion in this spec. See the section + [Syntax Non-goals](#-syntax-non-goals). + +- **"type/field pairs"** + + This was the original working name. However, there already exists more + established terminology for this concept, and we also wish to describe more + than just types on fields. + +- **"Field Coordinates"** + + "Field Coordinates" is already understood and used by the popular + [GraphQL Java](https://github.com/graphql-java/graphql-java) project. + + [Feedback in the August GraphQL Working Group meeting](https://youtu.be/FYF15RA9H3k?t=3786) + hinted that since we're targeting also describing arguments, _field_ + coordinates might not be the right name. Hence "Schema Coordinates" is chosen + instead, as a more generalized form of this. + +- **"GraphQL Coordinates"** + + Similar to Field Coordinates/Schema Coordinates - however, "GraphQL + Coordinates" is potentially ambiguous as to if it describes _schema_ members, + _query/document_ members or response object members. + +- **"Field path" / "GraphQL path"** + + [`path` exists as an attribute on `GraphQLResolveInfo`](https://github.com/graphql/graphql-js/blob/8f3d09b54260565/src/type/definition.js#L951). + + Given the following query: + + ```graphql + query { + searchBusinesses(name: "El Greco Deli") { + name + owner { + name + } + } + } + ``` + + `Person.name` in the response may be written as the following "field path": + + ```json + ["query", "searchBusinesses", 1, "owner", "name"] + ``` + + Note that here, the "path" is a serialized _response_ tree traversal, instead + of describing the location of the field in the _schema_. + + Since "path" is already used in GraphQL nomenclature to describe the location + of a field in a response, we'll avoid overloading this term. + +### Separator + +This RFC proposes using "`.`" as the separator character between a type and +field. The following have also been proposed: + +- `Foo::bar` +- `Foo#bar` +- `Foo->bar` +- `Foo~bar` +- `Foo:bar` + +"`.`" is already used in the existing implementations of field coordinates, hence +the suggested usage in this RFC. However, we may wish to consider one of the +alternatives above, should this conflict with existing or planned language +features. + +## 🙅 Syntax Non-goals + +This syntax consciously does not cover the following use cases: + +- **Wildcard selectors** + + Those familiar with `document.querySelector` may be expecting the ability to + pass "wildcards" or "star syntax" to be able to select multiple schema + elements. This implies multiple ways of _selecting_ a schema node. + + For example, `User.address` and `User.a*` might both resolve to `User.address`. + But `User.a*` could also ambiguously refer to `User.age`. + + It's unclear how wildcard expansion would work with respect to field + arguments\*, potentially violating the requirement of this schema to _uniquely_ + identify schema components. + + \* _(e.g. does `Query.getUser` also select all arguments on the `getUser` + field? Who knows! A discussion for another time.)_ + + A more general purpose schema selector language could be built on top of this + spec - however, we'll consider this **out of scope** for now. + +- **Directive applications** + + This spec does not support selecting applications of directive. + + For example: + + ```graphql + directive @private(scope: String!) on FIELD + + type User { + name: String + reviewCount: Int + friends: [User] + email: String @private(scope: 'loggedIn') + } + ``` + + You _can_ select the definition of the `private` directive and its arguments + (with `@private` and `@private(scope)` respectively), but you cannot select the + application of the `@private` on `User.email`. + + For the stated use cases of this RFC, it is more likely that consumers want to + select and track usage and changes to the definition of the custom directive + instead. + + If we _did_ want to support this, a syntax such as `User.email@private[0]` + could work. (The indexing is necessary since [multiple applications of the same + directive is allowed][multiple-directives], and each is considered unique.) + + [multiple-directives]: http://spec.graphql.org/draft/#sec-Directives-Are-Unique-Per-Location + +- **Union members** + + This spec does not support selecting members inside a union definition. + + For example: + + ```graphql + type Breakfast { + eggCount: Int + } + + type Lunch { + sandwichFilling: String + } + + union Meal = Breakfast | Lunch + ``` + + You may select the `Meal` definition (as "`Meal`"), but you may **not** select + members on `Meal` (e.g. `Meal.Breakfast` or `Meal.Lunch`). + + It is unclear what the use case for this would be, so we won't (yet?) support + this. In such cases, consumers may select type members directly (e.g. `Lunch`). + +## 🤔 Drawbacks / Open questions + +- https://github.com/graphql/graphql-spec/issues/735 discusses potential + conflicts with the upcoming namespaces proposal - would like to seek clarity on + this + +- Should we specify an algorithm for doing the query -> set of schema + coordinates? Or just hint/imply that this mapping theoretically exists? Is this + out of scope? + +### Answered questions + +- **Is this extensible enough?** The above issue discusses adding arguments as + part of this specification - we haven't touched on this here in order to keep + this RFC small, but we may wish to consider this in the future (e.g. + `Query.searchBusiness:name`). + + _Update:_ As discussed in the [August Working Group Meeting][notes], this RFC + now includes the ability to select field arguments + + [notes]: https://github.com/graphql/graphql-wg/blob/master/notes/2020-08-06.md#field-coordinates-rfc-15m-mark + +- **Would we want to add a method to graphql-js?** A `fieldCoordinateToFieldNode` + method (for example) may take in a field coordinate string and return a field + AST node to serve as a helper / reference implementation of the algorithm to + look up the field node. + + _Update:_ [This was discussed in the August Working Group Meeting][meeting] - + it was suggested to keep any utilities as third party libraries to avoid edge + ambiguity problems, and to be able to iterate faster. + + [meeting]: https://youtu.be/FYF15RA9H3k?t=2865 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 3633f4351..eedfa846a 100644 --- a/spec/GraphQL.md +++ b/spec/GraphQL.md @@ -128,3 +128,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 3c9c8f9c6f94ff2b9f26d6e9b3ebf359b9259c1f Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Tue, 17 Nov 2020 22:56:48 -0800 Subject: [PATCH 02/16] Update schema coordinates spec edit - Make examples table - Tweak the grammar definition --- rfcs/SchemaCoordinates.md | 2 +- spec/Appendix C -- Schema Coordinates.md | 125 +++++------------------ 2 files changed, 26 insertions(+), 101 deletions(-) diff --git a/rfcs/SchemaCoordinates.md b/rfcs/SchemaCoordinates.md index 4181cf707..50de0afbd 100644 --- a/rfcs/SchemaCoordinates.md +++ b/rfcs/SchemaCoordinates.md @@ -48,7 +48,7 @@ specification or name for this convention. [apq]: https://www.apollographql.com/docs/apollo-server/performance/apq/ 1. A **GitHub bot** may want to warn developers in a Pull Request comment - whenever the schema diff contains a breaking change. Schema selectors can be + whenever the schema diff contains a breaking change. Schema coordinates can be used to provide a list of which fields were broken. _Existing implementations: GraphQL Inspector (see "Prior Art")_ 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 109e3c6c2c36c47a98a92288dd0c76db614b7e55 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Tue, 17 Nov 2020 23:05:37 -0800 Subject: [PATCH 03/16] move spec edits to seperate pr --- spec/Appendix C -- Schema Coordinates.md | 93 ------------------------ spec/GraphQL.md | 4 +- 2 files changed, 1 insertion(+), 96 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 eedfa846a..96215372a 100644 --- a/spec/GraphQL.md +++ b/spec/GraphQL.md @@ -127,6 +127,4 @@ 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) +# [Appendix: Grammar Summary](Appendix%20B%20--%20Grammar%20Summary.md) \ No newline at end of file From e5ea9b5b51753ad7d340809aecde1a9e1d63eb43 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Tue, 17 Nov 2020 23:06:48 -0800 Subject: [PATCH 04/16] schema coordinates rfc: use colons for arguments --- rfcs/SchemaCoordinates.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/SchemaCoordinates.md b/rfcs/SchemaCoordinates.md index 50de0afbd..6843c8600 100644 --- a/rfcs/SchemaCoordinates.md +++ b/rfcs/SchemaCoordinates.md @@ -103,7 +103,7 @@ We can write the following list of Schema Coordinates: - `Business.owner` uniquely identifies the "owner" field on the "Business" type - `Query.searchBusinesses` uniquely identifies the "searchBusinesses" field on the "Query" type -- `Query.searchBusinesses(name)` uniquely identifies the "name" argument on the +- `Query.searchBusinesses(name:)` uniquely identifies the "name" argument on the "searchBusinesses" field on the "Query" type This RFC standardizes how we write coordinates GraphQL Schema members as above. From fe62f67b0a39b14bb4d4910fbe1cbff6c97880de Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Tue, 17 Nov 2020 23:07:46 -0800 Subject: [PATCH 05/16] schema coordinates rfc: fix newline --- spec/GraphQL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/GraphQL.md b/spec/GraphQL.md index 96215372a..3633f4351 100644 --- a/spec/GraphQL.md +++ b/spec/GraphQL.md @@ -127,4 +127,4 @@ 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) \ No newline at end of file +# [Appendix: Grammar Summary](Appendix%20B%20--%20Grammar%20Summary.md) From 3cd62423ad2c79892019095c3a6aa853f20579e5 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Thu, 19 Nov 2020 11:13:35 -0800 Subject: [PATCH 06/16] Apply suggestions from code review Co-authored-by: Benjie Gillam --- rfcs/SchemaCoordinates.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/rfcs/SchemaCoordinates.md b/rfcs/SchemaCoordinates.md index 6843c8600..70fc8679e 100644 --- a/rfcs/SchemaCoordinates.md +++ b/rfcs/SchemaCoordinates.md @@ -3,22 +3,21 @@ **Proposed by:** [Mark Larah](https://twitter.com/mark_larah) - Yelp This RFC proposes formalizing "Schema Coordinates" - a human readable syntax to -uniquely identify a type, field, or field argument defined in a GraphQL Schema. +uniquely identify a type, field, field argument, enum value, directive or directive argument defined in a GraphQL Schema. This should be listed as a non-normative note in the GraphQL specification to serve as an official reference for use by third party tooling. ## 📜 Problem Statement -Third party GraphQL tooling and libraries may wish to refer to a field, or set of -fields in a schema. Use cases include documentation, metrics and logging +GraphQL tooling and libraries may wish to refer to the various components of a GraphQL schema. Use cases include documentation, metrics and logging libraries. ![](https://i.fluffy.cc/5Cz9cpwLVsH1FsSF9VPVLwXvwrGpNh7q.png) _(Example shown from GraphiQL's documentation search tab)_ -There already exists a convention used by some third party libraries for writing +There already exists a convention used by some libraries and tools for writing out fields in a unique way for such purposes. However, there is no formal specification or name for this convention. @@ -173,7 +172,7 @@ From the query above, we may calculate the following list of schema coordinates: - `Business.owner` - `Person.name` -_`Query.searchBusinesses(name)` is also a valid member of the output set. The +_`Query.searchBusinesses(name:)` is also a valid member of the output set. The serialization algorithm may optionally choose to output all permutations of field arguments used, should this be specified._ @@ -301,7 +300,7 @@ This syntax consciously does not cover the following use cases: ``` You _can_ select the definition of the `private` directive and its arguments - (with `@private` and `@private(scope)` respectively), but you cannot select the + (with `@private` and `@private(scope:)` respectively), but you cannot select the application of the `@private` on `User.email`. For the stated use cases of this RFC, it is more likely that consumers want to From 9caf7196fe15021d96869e24bfc29a52c27a0c17 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Thu, 19 Nov 2020 11:20:57 -0800 Subject: [PATCH 07/16] Update rfcs/SchemaCoordinates.md Co-authored-by: Benjie Gillam --- rfcs/SchemaCoordinates.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/rfcs/SchemaCoordinates.md b/rfcs/SchemaCoordinates.md index 70fc8679e..fde11d47b 100644 --- a/rfcs/SchemaCoordinates.md +++ b/rfcs/SchemaCoordinates.md @@ -73,6 +73,28 @@ _Existing implementations: Apollo Studio (see "Prior Art")_ - There are **no proposed GraphQL runtime changes** - [Schema coordinate non-goals](#-syntax-non-goals) +## Proposed syntax + +### `Type` + +Refers to a named type (e.g. something represented by `__Type` in GraphQL introspection). + +### `Type.attribute` + +Refers to a named attribute on the named type. Not all types support this. For object types and interface types this is a field, for input objects this would be an input field, for enums this would be an enum value, for future GraphQL types this will relate to a related concept if they have one (e.g. for the [proposed "tagged" type](https://github.com/graphql/graphql-spec/pull/733) it would refer to the "member field"). + +### `Type.field(argName:)` + +Refers to a named argument on the named field of the named type. + +### `@directive` + +References the given named directive + +### `@directive(argName:)` + +References the named argument of the named directive. + ## ✨ Worked Examples For example, consider the following schema: From e423af304078ce9437eff01b1a684226abc5cf13 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Sat, 21 Nov 2020 11:15:07 -0800 Subject: [PATCH 08/16] add notes about Foo.bar.baz vs Foo.bar(baz:) --- rfcs/SchemaCoordinates.md | 95 +++++++++++++++++++++++++++++++-------- 1 file changed, 76 insertions(+), 19 deletions(-) diff --git a/rfcs/SchemaCoordinates.md b/rfcs/SchemaCoordinates.md index fde11d47b..37be9554b 100644 --- a/rfcs/SchemaCoordinates.md +++ b/rfcs/SchemaCoordinates.md @@ -3,15 +3,16 @@ **Proposed by:** [Mark Larah](https://twitter.com/mark_larah) - Yelp This RFC proposes formalizing "Schema Coordinates" - a human readable syntax to -uniquely identify a type, field, field argument, enum value, directive or directive argument defined in a GraphQL Schema. +uniquely identify a type, field, field argument, enum value, directive or +directive argument defined in a GraphQL Schema. This should be listed as a non-normative note in the GraphQL specification to serve as an official reference for use by third party tooling. ## 📜 Problem Statement -GraphQL tooling and libraries may wish to refer to the various components of a GraphQL schema. Use cases include documentation, metrics and logging -libraries. +GraphQL tooling and libraries may wish to refer to various components of a +GraphQL schema. Use cases include documentation, metrics and logging libraries. ![](https://i.fluffy.cc/5Cz9cpwLVsH1FsSF9VPVLwXvwrGpNh7q.png) @@ -27,7 +28,10 @@ specification or name for this convention. requested**. This may be implemented by incrementing a counter by the name of the schema coordinate for each field executed in a request. - _Existing implementations: Yelp (internal), Facebook (internal)_ + _Existing implementations: Yelp (internal), Facebook (internal), + [Shopify (API health report)][shopify-api-health]_ + + [shopify-api-health]: https://shopify.dev/concepts/about-apis/versioning/api-health 1. GraphiQL and other playgrounds / documentation sites want to show a list of **search results** when a user searches for a type or field name. We can @@ -65,7 +69,18 @@ specification or name for this convention. _Existing implementations: Apollo Studio (see "Prior Art")_ -## 🚫 What this RFC does _not_ propose +## 🥅 RFC Goals + +- There be one, unambiguous way to write a "schema coordinate" that refers to a + particular element in a GraphQL schema. (This is to avoid users having to + "simplify" more complex coordinates to produce a canonical representation.) +- Schema coordinate syntax should build off of existing de-facto standards + already adopted for this purpose (i.e. `Foo.bar`) +- Schema coordinate syntax is open for extension in the future. We should make + design choices that give us flexibility and anticipate future syntax needs + (based off of discussions around this RFC). + +## 🚫 RFC Non-goals - This does not cover "selectors" or "wildcard" syntax - e.g. `User.*`. _(See alternatives considered.)_ @@ -73,15 +88,24 @@ _Existing implementations: Apollo Studio (see "Prior Art")_ - There are **no proposed GraphQL runtime changes** - [Schema coordinate non-goals](#-syntax-non-goals) -## Proposed syntax +## 🧑‍💻 Proposed syntax ### `Type` -Refers to a named type (e.g. something represented by `__Type` in GraphQL introspection). +Refers to a named type (e.g. something represented by `__typename` in a GraphQL +introspection call). ### `Type.attribute` -Refers to a named attribute on the named type. Not all types support this. For object types and interface types this is a field, for input objects this would be an input field, for enums this would be an enum value, for future GraphQL types this will relate to a related concept if they have one (e.g. for the [proposed "tagged" type](https://github.com/graphql/graphql-spec/pull/733) it would refer to the "member field"). +Refers to a named attribute on the named type. + +Not all types support this. For object types and interface types this is a field, +for input objects this would be an input field, for enums this would be an enum +value, for future GraphQL types this will relate to a related concept if they +have one (e.g. for the [proposed "tagged" type][tagged-typed] it would refer to +the "member field"). + +[tagged-type]: https://github.com/graphql/graphql-spec/pull/733 ### `Type.field(argName:)` @@ -95,7 +119,7 @@ References the given named directive References the named argument of the named directive. -## ✨ Worked Examples +### ✨ Examples For example, consider the following schema: @@ -194,11 +218,12 @@ From the query above, we may calculate the following list of schema coordinates: - `Business.owner` - `Person.name` -_`Query.searchBusinesses(name:)` is also a valid member of the output set. The +`Query.searchBusinesses(name:)` is also a valid member of the output set. The serialization algorithm may optionally choose to output all permutations of field -arguments used, should this be specified._ +arguments used, should this be specified. -A library has been written to demonstrate this mapping: https://github.com/sharkcore/extract-schema-coordinates. +A library has been written to demonstrate this mapping: +. ## 🗳️ Alternatives considered @@ -290,7 +315,7 @@ This syntax consciously does not cover the following use cases: Those familiar with `document.querySelector` may be expecting the ability to pass "wildcards" or "star syntax" to be able to select multiple schema elements. This implies multiple ways of _selecting_ a schema node. - + For example, `User.address` and `User.a*` might both resolve to `User.address`. But `User.a*` could also ambiguously refer to `User.age`. @@ -304,10 +329,40 @@ This syntax consciously does not cover the following use cases: A more general purpose schema selector language could be built on top of this spec - however, we'll consider this **out of scope** for now. +- **Nested field paths** + + This spec does _not_ support selecting schema members with a path from a root + type (e.g. `Query`). + + For example, given this schema + + ```graphql + type User { + name: String + bestFriend: User + } + + type Query { + userById(id: String): User + } + ``` + + The following are invalid schema coordinates: + + - `Query.userById.name` + - `User.bestFriend.bestFriend.bestFriend.name` + + This violates a non-goal that there be one, unambiguous way to write a + schema coordinate to refer to a schema member. Both examples can be + "simplified" to `User.name`, which _is_ a valid schema coordinate. + + Should a use case for this arise in the future, a follow up RFC may investigate + how schema coordinates could work with "field paths" (e.g. `["query", "searchBusinesses", 1, "owner", "name"]`) to cover this. + - **Directive applications** - This spec does not support selecting applications of directive. - + This spec does _not_ support selecting applications of directive. + For example: ```graphql @@ -355,15 +410,17 @@ This syntax consciously does not cover the following use cases: You may select the `Meal` definition (as "`Meal`"), but you may **not** select members on `Meal` (e.g. `Meal.Breakfast` or `Meal.Lunch`). - + It is unclear what the use case for this would be, so we won't (yet?) support this. In such cases, consumers may select type members directly (e.g. `Lunch`). ## 🤔 Drawbacks / Open questions -- https://github.com/graphql/graphql-spec/issues/735 discusses potential - conflicts with the upcoming namespaces proposal - would like to seek clarity on - this +- Should arguments look like `Foo.bar.baz` instead of `Foo.bar(baz:)`? + + - See https://github.com/graphql/graphql-spec/pull/746#discussion_r526365127 + for discussion about this. + - TODO: Discuss next WG meeting and remove this note. - Should we specify an algorithm for doing the query -> set of schema coordinates? Or just hint/imply that this mapping theoretically exists? Is this From 078bcfcd1dcedb993efcfb4dbdac54de0d4ba6a3 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Sat, 21 Nov 2020 11:19:35 -0800 Subject: [PATCH 09/16] fix broken link --- rfcs/SchemaCoordinates.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/SchemaCoordinates.md b/rfcs/SchemaCoordinates.md index 37be9554b..4dc4ebd7a 100644 --- a/rfcs/SchemaCoordinates.md +++ b/rfcs/SchemaCoordinates.md @@ -102,7 +102,7 @@ Refers to a named attribute on the named type. Not all types support this. For object types and interface types this is a field, for input objects this would be an input field, for enums this would be an enum value, for future GraphQL types this will relate to a related concept if they -have one (e.g. for the [proposed "tagged" type][tagged-typed] it would refer to +have one (e.g. for the [proposed "tagged" type][tagged-type] it would refer to the "member field"). [tagged-type]: https://github.com/graphql/graphql-spec/pull/733 From f00ce5431614ee94166e9f883fb97eb5bcce0cba Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Sat, 21 Nov 2020 11:24:27 -0800 Subject: [PATCH 10/16] add directive example --- rfcs/SchemaCoordinates.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/rfcs/SchemaCoordinates.md b/rfcs/SchemaCoordinates.md index 4dc4ebd7a..585efcb29 100644 --- a/rfcs/SchemaCoordinates.md +++ b/rfcs/SchemaCoordinates.md @@ -124,8 +124,11 @@ References the named argument of the named directive. For example, consider the following schema: ```graphql +directive @private(scope: String!) on FIELD + type Person { name: String + email: String @private(scope: "loggedIn") } type Business { @@ -138,7 +141,7 @@ type Query { } ``` -We can write the following list of Schema Coordinates: +We can write the following schema coordinates: - `Person` uniquely identifies the the "Person" type - `Business` uniquely identifies the the "Business" type @@ -150,8 +153,9 @@ We can write the following list of Schema Coordinates: the "Query" type - `Query.searchBusinesses(name:)` uniquely identifies the "name" argument on the "searchBusinesses" field on the "Query" type - -This RFC standardizes how we write coordinates GraphQL Schema members as above. +- `@private` uniquely identifies the "private" directive +- `@private(scope:)` uniquely identifies the "scope" argument on the "private" + directive ## 🎨 Prior art From bfe9db9fbb7d4d4a75ea0e865d180271b876baa3 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Sat, 21 Nov 2020 11:27:17 -0800 Subject: [PATCH 11/16] emoji --- rfcs/SchemaCoordinates.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/SchemaCoordinates.md b/rfcs/SchemaCoordinates.md index 585efcb29..d6aead575 100644 --- a/rfcs/SchemaCoordinates.md +++ b/rfcs/SchemaCoordinates.md @@ -69,7 +69,7 @@ specification or name for this convention. _Existing implementations: Apollo Studio (see "Prior Art")_ -## 🥅 RFC Goals +## ✅ RFC Goals - There be one, unambiguous way to write a "schema coordinate" that refers to a particular element in a GraphQL schema. (This is to avoid users having to From 80f78a35b36c830b162a8641f979cea4e4cc2376 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Sun, 3 Jan 2021 16:10:46 -0800 Subject: [PATCH 12/16] capture discussion about argument syntax --- rfcs/SchemaCoordinates.md | 81 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 4 deletions(-) diff --git a/rfcs/SchemaCoordinates.md b/rfcs/SchemaCoordinates.md index d6aead575..c7f33d6d6 100644 --- a/rfcs/SchemaCoordinates.md +++ b/rfcs/SchemaCoordinates.md @@ -310,6 +310,79 @@ the suggested usage in this RFC. However, we may wish to consider one of the alternatives above, should this conflict with existing or planned language features. +### Field Arguments + +We have discussed multiple options for selecting arguments on fields. ([PR][pr], +and [December WG Meeting][wg-meeting]). For example, consider the following +schema: + +[pr]: https://github.com/graphql/graphql-spec/pull/746#discussion_r526243627 +[wg-meeting]: https://youtu.be/Duh4MRXQRQA?t=2506 + +```graphql +type Query { + rollDice(numDice: Int, numSides: Int): Int +} +``` + +We may want to refer to the `numDice` argument in a schema selector. Two options +for this syntax are: + +1. `Query.rollDice.numDice` +1. `Query.rollDice(numDice:)` + +#### Pros for `Query.rollDice.numDice` + +- Less bytes/characters to type +- May allow for extension to include nested "field paths" (e.g. Foo.bar.Baz.qux...) + +#### Pros for `Query.rollDice(numDice:)` + +- Indicating arguments with colons disambiguates against other types of schema + nodes. For those unfamiliar with schema selectors, it may be unclear if the + third dot separated item refers to a directive or a child object etc. +- Using trailing colons for arguments is borrowed from other languages (e.g. + [Swift][swift]). This may indicate to users who are unfamiliar with schema + coordinates, but recognize this from other languages, that `numDice:` refers + to an argument. The function parentheses and colons more strongly communicate + "this is an argument!" than a second dot separator. + +#### Decision + +We are choosing `Query.rollDice(numDice:)` to optimize for **readability** and +**extensibility**. + +Given our expected use cases, we assume Schema Coordinates will be _read_ more +often than they are _written_ (e.g. error messages in a stack trace from a +schema linting tool). Readers may be unfamiliar with its syntax. We want to +"hint" as much as possible the meaning of the coordinates in its syntax. We +think `(numDice:)` more clearly communicates that "numDice" is an argument, over +`.numDice`. + +In addition, we want to be mindful of extensions to this syntax in the future. +Using dots only as a separator may overload the meaning of elements in schema +coordinates in the future. (If we capture new schema node types, or nested +paths.) + +> We should make sure that the spec enables future innovation including using it +> for things other than schema coordinates. To my mind the (foo:) syntax is more +> flexible in this regard. For example, I can imagine referring to: +> +> 1. `Foo.bar(baz:.qux)`: the qux field of the input object referred to from the +> baz argument of the bar field on the Foo type. +> 2. `Foo.bar(baz:).qux`: the qux field on the return type of the bar field +> (with baz: argument) of the Foo type. +> 3. `Foo.bar.baz.qux`: the qux field of the return type of the baz field on the +> return type of the bar field on type Foo. +> +> If we were to only use periods then all of these would come out the same as +> `Foo.bar.baz.qux`, and this ambiguity precludes this kind of reusal of the +> schema-coordinates syntax for this use case (which is outside the scope of the +> schema coordinates spec, for sure, but is still a potential use-case for the +> syntax). +> +> ~ [benjie](https://github.com/graphql/graphql-spec/pull/746#discussion_r527639917) + ## 🙅 Syntax Non-goals This syntax consciously does not cover the following use cases: @@ -373,10 +446,10 @@ This syntax consciously does not cover the following use cases: directive @private(scope: String!) on FIELD type User { - name: String - reviewCount: Int - friends: [User] - email: String @private(scope: 'loggedIn') + name: String + reviewCount: Int + friends: [User] + email: String @private(scope: "loggedIn") } ``` From 0ae4b46ecf947159c9fa07f4f56b61fde59ca088 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Sun, 3 Jan 2021 16:24:26 -0800 Subject: [PATCH 13/16] remove open question about argument syntax --- rfcs/SchemaCoordinates.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/rfcs/SchemaCoordinates.md b/rfcs/SchemaCoordinates.md index c7f33d6d6..99d336db3 100644 --- a/rfcs/SchemaCoordinates.md +++ b/rfcs/SchemaCoordinates.md @@ -493,12 +493,6 @@ This syntax consciously does not cover the following use cases: ## 🤔 Drawbacks / Open questions -- Should arguments look like `Foo.bar.baz` instead of `Foo.bar(baz:)`? - - - See https://github.com/graphql/graphql-spec/pull/746#discussion_r526365127 - for discussion about this. - - TODO: Discuss next WG meeting and remove this note. - - Should we specify an algorithm for doing the query -> set of schema coordinates? Or just hint/imply that this mapping theoretically exists? Is this out of scope? From da052fecedba3dd75f006b1d98215c25e6b3ee8d Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Sun, 3 Jan 2021 18:02:09 -0800 Subject: [PATCH 14/16] add prior usage --- rfcs/SchemaCoordinates.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rfcs/SchemaCoordinates.md b/rfcs/SchemaCoordinates.md index 99d336db3..574009f89 100644 --- a/rfcs/SchemaCoordinates.md +++ b/rfcs/SchemaCoordinates.md @@ -335,6 +335,9 @@ for this syntax are: - Less bytes/characters to type - May allow for extension to include nested "field paths" (e.g. Foo.bar.Baz.qux...) +- [Prior usage][graphiql-usage] of this syntax to represent state internally + +[graphiql-usage]: https://github.com/graphql/graphql-spec/pull/746#issuecomment-752941039 #### Pros for `Query.rollDice(numDice:)` From 1f9cfc6ed24315da35851a65ca162d83e1534623 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Mon, 4 Jan 2021 09:34:26 -0800 Subject: [PATCH 15/16] Update rfcs/SchemaCoordinates.md Co-authored-by: Benjie Gillam --- rfcs/SchemaCoordinates.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/SchemaCoordinates.md b/rfcs/SchemaCoordinates.md index 574009f89..d32d94b77 100644 --- a/rfcs/SchemaCoordinates.md +++ b/rfcs/SchemaCoordinates.md @@ -371,7 +371,7 @@ paths.) > for things other than schema coordinates. To my mind the (foo:) syntax is more > flexible in this regard. For example, I can imagine referring to: > -> 1. `Foo.bar(baz:.qux)`: the qux field of the input object referred to from the +> 1. `Foo.bar(baz.qux:)`: the qux field of the input object referred to from the > baz argument of the bar field on the Foo type. > 2. `Foo.bar(baz:).qux`: the qux field on the return type of the bar field > (with baz: argument) of the Foo type. From d8396c9cd01f73ed1cb559698c7c02241ddee0c5 Mon Sep 17 00:00:00 2001 From: Mark Larah Date: Mon, 4 Jan 2021 09:41:57 -0800 Subject: [PATCH 16/16] Remove outdated section --- rfcs/SchemaCoordinates.md | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/rfcs/SchemaCoordinates.md b/rfcs/SchemaCoordinates.md index d32d94b77..ccbc62af8 100644 --- a/rfcs/SchemaCoordinates.md +++ b/rfcs/SchemaCoordinates.md @@ -494,23 +494,7 @@ This syntax consciously does not cover the following use cases: It is unclear what the use case for this would be, so we won't (yet?) support this. In such cases, consumers may select type members directly (e.g. `Lunch`). -## 🤔 Drawbacks / Open questions - -- Should we specify an algorithm for doing the query -> set of schema - coordinates? Or just hint/imply that this mapping theoretically exists? Is this - out of scope? - -### Answered questions - -- **Is this extensible enough?** The above issue discusses adding arguments as - part of this specification - we haven't touched on this here in order to keep - this RFC small, but we may wish to consider this in the future (e.g. - `Query.searchBusiness:name`). - - _Update:_ As discussed in the [August Working Group Meeting][notes], this RFC - now includes the ability to select field arguments - - [notes]: https://github.com/graphql/graphql-wg/blob/master/notes/2020-08-06.md#field-coordinates-rfc-15m-mark +## Answered questions - **Would we want to add a method to graphql-js?** A `fieldCoordinateToFieldNode` method (for example) may take in a field coordinate string and return a field