Skip to content

Commit 9ec15e3

Browse files
benjieleebyron
andauthored
Spec edits to reduce "query ambiguity" (#777)
* Spec edits to reduce "query ambiguity" * Editorialize change sites I went through this editorial in two passes. One where I tuned the usage of "operation", "request", and "selection set". I hopefully made these spots slightly clearer, but I'm open to feedback. Second pass was more freeform prose edits in cases where I thought the intended ideas could have been clearer and avoid the query ambiguity in the first place. Co-authored-by: Lee Byron <lee.byron@robinhood.com>
1 parent f474e66 commit 9ec15e3

9 files changed

+107
-105
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ move forward. See editor Lee Byron talk about
5151

5252
Once a query is written, it should always mean the same thing and return the
5353
same shaped result. Future changes should not change the meaning of existing
54-
schema or queries or in any other way cause an existing compliant GraphQL
54+
schema or requests or in any other way cause an existing compliant GraphQL
5555
service to become non-compliant for prior versions of the spec.
5656

5757
* **Performance is a feature**

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ type Droid implements Character {
208208
We're missing one last piece: an entry point into the type system.
209209

210210
When we define a schema, we define an object type that is the basis for all
211-
queries. The name of this type is `Query` by convention, and it describes
211+
query operations. The name of this type is `Query` by convention, and it describes
212212
our public, top-level API. Our `Query` type for this example will look like
213213
this:
214214

spec/Section 1 -- Overview.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Which produces the resulting data (in JSON):
2626
```
2727

2828
GraphQL is not a programming language capable of arbitrary computation, but is
29-
instead a language used to query application services that have
29+
instead a language used to make requests to application services that have
3030
capabilities defined in this specification. GraphQL does not mandate a
3131
particular programming language or storage system for application services that
3232
implement it. Instead, application services take their capabilities and map them

spec/Section 2 -- Language.md

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Clients use the GraphQL query language to make requests to a GraphQL service.
44
We refer to these request sources as documents. A document may contain
55
operations (queries, mutations, and subscriptions) as well as fragments, a
6-
common unit of composition allowing for query reuse.
6+
common unit of composition allowing for data requirement reuse.
77

88
A GraphQL document is defined as a syntactic grammar where terminal symbols are
99
tokens (indivisible lexical units). These tokens are defined in a lexical
@@ -337,8 +337,8 @@ under-fetching data.
337337
}
338338
```
339339

340-
In this query, the `id`, `firstName`, and `lastName` fields form a selection
341-
set. Selection sets may also contain fragment references.
340+
In this query operation, the `id`, `firstName`, and `lastName` fields form a
341+
selection set. Selection sets may also contain fragment references.
342342

343343

344344
## Fields
@@ -438,7 +438,7 @@ Many arguments can exist for a given field:
438438
Arguments may be provided in any syntactic order and maintain identical
439439
semantic meaning.
440440

441-
These two queries are semantically identical:
441+
These two operations are semantically identical:
442442

443443
```graphql example
444444
{
@@ -546,7 +546,7 @@ query noFragments {
546546
```
547547

548548
The repeated fields could be extracted into a fragment and composed by
549-
a parent fragment or query.
549+
a parent fragment or operation.
550550

551551
```graphql example
552552
query withFragments {
@@ -567,8 +567,8 @@ fragment friendFields on User {
567567
}
568568
```
569569

570-
Fragments are consumed by using the spread operator (`...`). All fields selected
571-
by the fragment will be added to the query field selection at the same level
570+
Fragments are consumed by using the spread operator (`...`). All fields
571+
selected by the fragment will be added to the field selection at the same level
572572
as the fragment invocation. This happens through multiple levels of fragment
573573
spreads.
574574

@@ -597,7 +597,7 @@ fragment standardProfilePic on User {
597597
}
598598
```
599599

600-
The queries `noFragments`, `withFragments`, and `withNestedFragments` all
600+
The operations `noFragments`, `withFragments`, and `withNestedFragments` all
601601
produce the same response object.
602602

603603

@@ -616,7 +616,7 @@ Fragments can be specified on object types, interfaces, and unions.
616616
Selections within fragments only return values when the concrete type of the object
617617
it is operating on matches the type of the fragment.
618618

619-
For example in this query on the Facebook data model:
619+
For example in this operation using the Facebook data model:
620620

621621
```graphql example
622622
query FragmentTyping {
@@ -1049,7 +1049,7 @@ literal representation of input objects as "object literals."
10491049
Input object fields may be provided in any syntactic order and maintain
10501050
identical semantic meaning.
10511051

1052-
These two queries are semantically identical:
1052+
These two operations are semantically identical:
10531053

10541054
```graphql example
10551055
{
@@ -1096,7 +1096,9 @@ If not defined as constant (for example, in {DefaultValue}), a {Variable} can be
10961096
supplied for an input value.
10971097

10981098
Variables must be defined at the top of an operation and are in scope
1099-
throughout the execution of that operation.
1099+
throughout the execution of that operation. Values for those variables are
1100+
provided to a GraphQL service as part of a request so they may be substituted
1101+
in during execution.
11001102

11011103
In this example, we want to fetch a profile picture size based on the size
11021104
of a particular device:
@@ -1111,10 +1113,8 @@ query getZuckProfile($devicePicSize: Int) {
11111113
}
11121114
```
11131115

1114-
Values for those variables are provided to a GraphQL service along with a
1115-
request so they may be substituted during execution. If providing JSON for the
1116-
variables' values, we could run this query and request profilePic of
1117-
size `60` width:
1116+
If providing JSON for the variables' values, we could request a `profilePic` of
1117+
size `60`:
11181118

11191119
```json example
11201120
{
@@ -1124,11 +1124,10 @@ size `60` width:
11241124

11251125
**Variable use within Fragments**
11261126

1127-
Query variables can be used within fragments. Query variables have global scope
1128-
with a given operation, so a variable used within a fragment must be declared
1129-
in any top-level operation that transitively consumes that fragment. If
1130-
a variable is referenced in a fragment and is included by an operation that does
1131-
not define that variable, the operation cannot be executed.
1127+
Variables can be used within fragments. Variables have global scope with a given operation, so a variable used within a fragment must be declared in any
1128+
top-level operation that transitively consumes that fragment. If a variable is
1129+
referenced in a fragment and is included by an operation that does not define
1130+
that variable, that operation is invalid (see [All Variable Uses Defined](#sec-All-Variable-Uses-Defined)).
11321131

11331132

11341133
## Type References
@@ -1146,9 +1145,9 @@ NonNullType :
11461145
- NamedType !
11471146
- ListType !
11481147

1149-
GraphQL describes the types of data expected by query variables. Input types
1150-
may be lists of another input type, or a non-null variant of any other
1151-
input type.
1148+
GraphQL describes the types of data expected by arguments and variables.
1149+
Input types may be lists of another input type, or a non-null variant of any
1150+
other input type.
11521151

11531152
**Semantics**
11541153

@@ -1188,8 +1187,8 @@ including or skipping a field. Directives provide this by describing additional
11881187
Directives have a name along with a list of arguments which may accept values
11891188
of any input type.
11901189

1191-
Directives can be used to describe additional information for types, fields, fragments
1192-
and operations.
1190+
Directives can be used to describe additional information for types, fields,
1191+
fragments and operations.
11931192

11941193
As future versions of GraphQL adopt new configurable execution capabilities,
11951194
they may be exposed via directives. GraphQL services and tools may also provide

spec/Section 3 -- Type System.md

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# Type System
22

33
The GraphQL Type system describes the capabilities of a GraphQL service and is
4-
used to determine if a query is valid. The type system also describes the
5-
input types of query variables to determine if values provided at runtime
6-
are valid.
4+
used to determine if a requested operation is valid, to guarantee the type of
5+
response results, and describes the input types of variables to determine if
6+
values provided at request time are valid.
77

88
TypeSystemDocument : TypeSystemDefinition+
99

@@ -79,7 +79,7 @@ schema {
7979
}
8080
8181
"""
82-
Root type for all your queries
82+
Root type for all your query operations
8383
"""
8484
type Query {
8585
"""
@@ -191,7 +191,7 @@ When using the type system definition language, a document must include at most
191191
one {`schema`} definition.
192192

193193
In this example, a GraphQL schema is defined with both query and mutation
194-
root types:
194+
root operation types:
195195

196196
```graphql example
197197
schema {
@@ -424,8 +424,8 @@ raised (input values are validated before execution begins).
424424

425425
GraphQL has different constant literals to represent integer and floating-point
426426
input values, and coercion rules may apply differently depending on which type
427-
of input value is encountered. GraphQL may be parameterized by query variables,
428-
the values of which are often serialized when sent over a transport like HTTP. Since
427+
of input value is encountered. GraphQL may be parameterized by variables, the
428+
values of which are often serialized when sent over a transport like HTTP. Since
429429
some common serializations (ex. JSON) do not discriminate between integer
430430
and floating-point values, they are interpreted as an integer input value if
431431
they have an empty fractional part (ex. `1.0`) and otherwise as floating-point
@@ -601,14 +601,15 @@ FieldsDefinition : { FieldDefinition+ }
601601

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

604-
GraphQL queries are hierarchical and composed, describing a tree of information.
605-
While Scalar types describe the leaf values of these hierarchical queries, Objects
606-
describe the intermediate levels.
604+
GraphQL operations are hierarchical and composed, describing a tree of
605+
information. While Scalar types describe the leaf values of these hierarchical
606+
operations, Objects describe the intermediate levels.
607607

608608
GraphQL Objects represent a list of named fields, each of which yield a value of
609609
a specific type. Object values should be serialized as ordered maps, where the
610-
queried field names (or aliases) are the keys and the result of evaluating
611-
the field is the value, ordered by the order in which they appear in the query.
610+
selected field names (or aliases) are the keys and the result of evaluating
611+
the field is the value, ordered by the order in which they appear in
612+
the selection set.
612613

613614
All fields defined within an Object type must not have a name which begins with
614615
{"__"} (two underscores), as this is used exclusively by GraphQL's
@@ -687,8 +688,8 @@ type Person {
687688
}
688689
```
689690

690-
Valid queries must supply a nested field set for a field that returns
691-
an object, so this query is not valid:
691+
Valid operations must supply a nested field set for any field that returns an
692+
object, so this operation is not valid:
692693

693694
```graphql counter-example
694695
{
@@ -722,7 +723,7 @@ And will yield the subset of each object type queried:
722723
**Field Ordering**
723724

724725
When querying an Object, the resulting mapping of fields are conceptually
725-
ordered in the same order in which they were encountered during query execution,
726+
ordered in the same order in which they were encountered during execution,
726727
excluding fragments for which the type does not apply and fields or
727728
fragments that are skipped via `@skip` or `@include` directives. This ordering
728729
is correctly produced when using the {CollectFields()} algorithm.
@@ -920,10 +921,10 @@ type Person {
920921
}
921922
```
922923

923-
GraphQL queries can optionally specify arguments to their fields to provide
924+
Operations can optionally specify arguments to their fields to provide
924925
these arguments.
925926

926-
This example query:
927+
This example operation:
927928

928929
```graphql example
929930
{
@@ -932,7 +933,7 @@ This example query:
932933
}
933934
```
934935

935-
May yield the result:
936+
May return the result:
936937

937938
```json example
938939
{
@@ -948,9 +949,9 @@ Object, Interface, or Union type).
948949
### Field Deprecation
949950

950951
Fields in an object may be marked as deprecated as deemed necessary by the
951-
application. It is still legal to query for these fields (to ensure existing
952-
clients are not broken by the change), but the fields should be appropriately
953-
treated in documentation and tooling.
952+
application. It is still legal to include these fields in a selection set
953+
(to ensure existing clients are not broken by the change), but the fields should
954+
be appropriately treated in documentation and tooling.
954955

955956
When using the type system definition language, `@deprecated` directives are
956957
used to indicate that a field is deprecated:
@@ -1062,7 +1063,7 @@ type Contact {
10621063
}
10631064
```
10641065

1065-
This allows us to write a query for a `Contact` that can select the
1066+
This allows us to write a selection set for a `Contact` that can select the
10661067
common fields.
10671068

10681069
```graphql example
@@ -1074,10 +1075,10 @@ common fields.
10741075
}
10751076
```
10761077

1077-
When querying for fields on an interface type, only those fields declared on
1078+
When selecting fields on an interface type, only those fields declared on
10781079
the interface may be queried. In the above example, `entity` returns a
10791080
`NamedEntity`, and `name` is defined on `NamedEntity`, so it is valid. However,
1080-
the following would not be a valid query:
1081+
the following would not be a valid selection set against `Contact`:
10811082

10821083
```graphql counter-example
10831084
{
@@ -1091,7 +1092,7 @@ the following would not be a valid query:
10911092

10921093
because `entity` refers to a `NamedEntity`, and `age` is not defined on that
10931094
interface. Querying for `age` is only valid when the result of `entity` is a
1094-
`Person`; the query can express this using a fragment or an inline fragment:
1095+
`Person`; this can be expressed using a fragment or an inline fragment:
10951096

10961097
```graphql example
10971098
{
@@ -1294,11 +1295,9 @@ type SearchQuery {
12941295
}
12951296
```
12961297

1297-
When querying the `firstSearchResult` field of type `SearchQuery`, the
1298-
query would ask for all fields inside of a fragment indicating the appropriate
1299-
type. If the query wanted the name if the result was a Person, and the height if
1300-
it was a photo, the following query is invalid, because the union itself
1301-
defines no fields:
1298+
In this example, a query operation wants the name if the result was a Person,
1299+
and the height if it was a photo. However because a union itself defines no
1300+
fields, this could be ambiguous and is invalid.
13021301

13031302
```graphql counter-example
13041303
{
@@ -1309,7 +1308,7 @@ defines no fields:
13091308
}
13101309
```
13111310

1312-
Instead, the query would be:
1311+
A valid operation includes typed fragments (in this example, inline fragments):
13131312

13141313
```graphql example
13151314
{
@@ -1415,7 +1414,7 @@ reasonable coercion is not possible they must raise a field error.
14151414
GraphQL has a constant literal to represent enum input values. GraphQL string
14161415
literals must not be accepted as an enum input and instead raise a request error.
14171416

1418-
Query variable transport serializations which have a different representation
1417+
Variable transport serializations which have a different representation
14191418
for non-string symbolic values (for example, [EDN](https://github.com/edn-format/edn))
14201419
should only allow such values as enum input values. Otherwise, for most
14211420
transport serializations that do not, strings may be interpreted as the enum
@@ -1709,9 +1708,9 @@ exclamation mark is used to denote a field that uses a Non-Null type like this:
17091708

17101709
**Nullable vs. Optional**
17111710

1712-
Fields are *always* optional within the context of a query, a field may be
1713-
omitted and the query is still valid. However fields that return Non-Null types
1714-
will never return the value {null} if queried.
1711+
Fields are *always* optional within the context of a selection set, a field may
1712+
be omitted and the selection set is still valid. However fields that return
1713+
Non-Null types will never return the value {null} if queried.
17151714

17161715
Inputs (such as field arguments), are always optional by default. However a
17171716
non-null input type is required. In addition to not accepting the value {null},

0 commit comments

Comments
 (0)