Skip to content

Commit

Permalink
Add definition of "selection set" and clarify serial execution exampl…
Browse files Browse the repository at this point in the history
…es (#1032)

* Define selection set

* Consistent casing of 'selection set'

* Convert an example to a mutation operation

* Add operation name and variables
  • Loading branch information
benjie committed Apr 4, 2024
1 parent 32d24f6 commit b5ecff0
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 43 deletions.
20 changes: 12 additions & 8 deletions spec/Section 2 -- Language.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,8 @@ There are three types of operations that GraphQL models:
- subscription - a long-lived request that fetches data in response to source
events.

Each operation is represented by an optional operation name and a selection set.
Each operation is represented by an optional operation name and a _selection
set_.

For example, this mutation operation might "like" a story and then retrieve the
new number of likes:
Expand Down Expand Up @@ -337,6 +338,9 @@ An operation selects the set of information it needs, and will receive exactly
that information and nothing more, avoiding over-fetching and under-fetching
data.

:: A _selection set_ defines an ordered set of selections (fields, fragment
spreads and inline fragments) against an object, union or interface type.

```graphql example
{
id
Expand All @@ -346,14 +350,14 @@ data.
```

In this query operation, the `id`, `firstName`, and `lastName` fields form a
selection set. Selection sets may also contain fragment references.
_selection set_. Selection sets may also contain fragment references.

## Fields

Field : Alias? Name Arguments? Directives? SelectionSet?

A selection set is primarily composed of fields. A field describes one discrete
piece of information available to request within a selection set.
A _selection set_ is primarily composed of fields. A field describes one
discrete piece of information available to request within a selection set.

Some fields describe complex data or relationships to other data. In order to
further explore this data, a field may itself contain a selection set, allowing
Expand Down Expand Up @@ -381,7 +385,7 @@ down to scalar values.
}
```

Fields in the top-level selection set of an operation often represent some
Fields in the top-level _selection set_ of an operation often represent some
information that is globally accessible to your application and its current
viewer. Some typical examples of these top fields include references to a
current logged-in viewer, or accessing certain types of data referenced by a
Expand Down Expand Up @@ -667,9 +671,9 @@ be present and `likers` will not. Conversely when the result is a `Page`,

InlineFragment : ... TypeCondition? Directives? SelectionSet

Fragments can also be defined inline within a selection set. This is useful for
conditionally including fields based on a type condition or applying a directive
to a selection set.
Fragments can also be defined inline within a _selection set_. This is useful
for conditionally including fields based on a type condition or applying a
directive to a selection set.

This feature of standard fragment inclusion was demonstrated in the
`query FragmentTyping` example above. We could accomplish the same thing using
Expand Down
14 changes: 7 additions & 7 deletions spec/Section 3 -- Type System.md
Original file line number Diff line number Diff line change
Expand Up @@ -677,8 +677,8 @@ operations, Objects describe the intermediate levels.
GraphQL Objects represent a list of named fields, each of which yield a value of
a specific type. Object values should be serialized as ordered maps, where the
selected field names (or aliases) are the keys and the result of evaluating the
field is the value, ordered by the order in which they appear in the selection
set.
field is the value, ordered by the order in which they appear in the _selection
set_.

All fields defined within an Object type must not have a name which begins with
{"\_\_"} (two underscores), as this is used exclusively by GraphQL's
Expand Down Expand Up @@ -1026,7 +1026,7 @@ Object, Interface, or Union type).
### Field Deprecation

Fields in an object may be marked as deprecated as deemed necessary by the
application. It is still legal to include these fields in a selection set (to
application. It is still legal to include these fields in a _selection set_ (to
ensure existing clients are not broken by the change), but the fields should be
appropriately treated in documentation and tooling.

Expand Down Expand Up @@ -1142,7 +1142,7 @@ type Contact {
}
```

This allows us to write a selection set for a `Contact` that can select the
This allows us to write a _selection set_ for a `Contact` that can select the
common fields.

```graphql example
Expand Down Expand Up @@ -1795,9 +1795,9 @@ to denote a field that uses a Non-Null type like this: `name: String!`.

**Nullable vs. Optional**

Fields are _always_ optional within the context of a selection set, a field may
be omitted and the selection set is still valid (so long as the selection set
does not become empty). However fields that return Non-Null types will never
Fields are _always_ optional within the context of a _selection set_, a field
may be omitted and the selection set is still valid (so long as the selection
set does not become empty). However fields that return Non-Null types will never
return the value {null} if queried.

Inputs (such as field arguments), are always optional by default. However a
Expand Down
2 changes: 1 addition & 1 deletion spec/Section 4 -- Introspection.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ underscores {"\_\_"}.

## Type Name Introspection

GraphQL supports type name introspection within any selection set in an
GraphQL supports type name introspection within any _selection set_ in an
operation, with the single exception of selections at the root of a subscription
operation. Type name introspection is accomplished via the meta-field
`__typename: String!` on any Object, Interface, or Union. It returns the name of
Expand Down
42 changes: 22 additions & 20 deletions spec/Section 6 -- Execution.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,16 +121,16 @@ respectively.
### Query

If the operation is a query, the result of the operation is the result of
executing the operation’s top level selection set with the query root operation
type.
executing the operation’s top level _selection set_ with the query root
operation type.

An initial value may be provided when executing a query operation.

ExecuteQuery(query, schema, variableValues, initialValue):

- Let {queryType} be the root Query type in {schema}.
- Assert: {queryType} is an Object type.
- Let {selectionSet} be the top level Selection Set in {query}.
- Let {selectionSet} be the top level selection set in {query}.
- Let {data} be the result of running {ExecuteSelectionSet(selectionSet,
queryType, initialValue, variableValues)} _normally_ (allowing
parallelization).
Expand All @@ -141,7 +141,7 @@ ExecuteQuery(query, schema, variableValues, initialValue):
### Mutation

If the operation is a mutation, the result of the operation is the result of
executing the operation’s top level selection set on the mutation root object
executing the operation’s top level _selection set_ on the mutation root object
type. This selection set should be executed serially.

It is expected that the top level fields in a mutation operation perform
Expand All @@ -152,7 +152,7 @@ ExecuteMutation(mutation, schema, variableValues, initialValue):

- Let {mutationType} be the root Mutation type in {schema}.
- Assert: {mutationType} is an Object type.
- Let {selectionSet} be the top level Selection Set in {mutation}.
- Let {selectionSet} be the top level selection set in {mutation}.
- Let {data} be the result of running {ExecuteSelectionSet(selectionSet,
mutationType, initialValue, variableValues)} _serially_.
- Let {errors} be the list of all _field error_ raised while executing the
Expand Down Expand Up @@ -255,7 +255,7 @@ CreateSourceEventStream(subscription, schema, variableValues, initialValue):

- Let {subscriptionType} be the root Subscription type in {schema}.
- Assert: {subscriptionType} is an Object type.
- Let {selectionSet} be the top level Selection Set in {subscription}.
- Let {selectionSet} be the top level selection set in {subscription}.
- Let {groupedFieldSet} be the result of {CollectFields(subscriptionType,
selectionSet, variableValues)}.
- If {groupedFieldSet} does not have exactly one entry, raise a _request error_.
Expand Down Expand Up @@ -285,7 +285,7 @@ operation type.
#### Response Stream

Each event in the underlying Source Stream triggers execution of the
subscription selection set using that event as a root value.
subscription _selection set_ using that event as a root value.

MapSourceToResponseEvent(sourceStream, subscription, schema, variableValues):

Expand All @@ -300,7 +300,7 @@ ExecuteSubscriptionEvent(subscription, schema, variableValues, initialValue):

- Let {subscriptionType} be the root Subscription type in {schema}.
- Assert: {subscriptionType} is an Object type.
- Let {selectionSet} be the top level Selection Set in {subscription}.
- Let {selectionSet} be the top level selection set in {subscription}.
- Let {data} be the result of running {ExecuteSelectionSet(selectionSet,
subscriptionType, initialValue, variableValues)} _normally_ (allowing
parallelization).
Expand All @@ -324,9 +324,9 @@ Unsubscribe(responseStream):

## Executing Selection Sets

To execute a selection set, the object value being evaluated and the object type
need to be known, as well as whether it must be executed serially, or may be
executed in parallel.
To execute a _selection set_, the object value being evaluated and the object
type need to be known, as well as whether it must be executed serially, or may
be executed in parallel.

First, the selection set is turned into a grouped field set; then, each
represented field in the grouped field set produces an entry into a response
Expand Down Expand Up @@ -396,10 +396,11 @@ entry from the grouped field set in the order provided in the grouped field set.
It must determine the corresponding entry in the result map for each item to
completion before it continues on to the next item in the grouped field set:

For example, given the following selection set to be executed serially:
For example, given the following mutation operation, the root _selection set_
must be executed serially:

```graphql example
{
mutation ChangeBirthdayAndAddress($newBirthday: String!, $newAddress: String!) {
changeBirthday(birthday: $newBirthday) {
month
}
Expand All @@ -409,7 +410,7 @@ For example, given the following selection set to be executed serially:
}
```

The executor must, in serial:
Therefore the executor must, in serial:

- Run {ExecuteField()} for `changeBirthday`, which during {CompleteValue()} will
execute the `{ month }` sub-selection set normally.
Expand All @@ -418,9 +419,10 @@ The executor must, in serial:

As an illustrative example, let's assume we have a mutation field
`changeTheNumber` that returns an object containing one field, `theNumber`. If
we execute the following selection set serially:
we execute the following _selection set_ serially:

```graphql example
# Note: This is a selection set, not a full document using the query shorthand.
{
first: changeTheNumber(newNumber: 1) {
theNumber
Expand All @@ -443,7 +445,7 @@ The executor will execute the following serially:
- Resolve the `changeTheNumber(newNumber: 2)` field
- Execute the `{ theNumber }` sub-selection set of `third` normally

A correct executor must generate the following result for that selection set:
A correct executor must generate the following result for that _selection set_:

```json example
{
Expand All @@ -461,7 +463,7 @@ A correct executor must generate the following result for that selection set:

### Field Collection

Before execution, the selection set is converted to a grouped field set by
Before execution, the _selection set_ is converted to a grouped field set by
calling {CollectFields()}. Each entry in the grouped field set is a list of
fields that share a response key (the alias if defined, otherwise the field
name). This ensures all fields with the same response key (including those in
Expand Down Expand Up @@ -740,9 +742,9 @@ ResolveAbstractType(abstractType, objectValue):

**Merging Selection Sets**

When more than one field of the same name is executed in parallel, their
selection sets are merged together when completing the value in order to
continue execution of the sub-selection sets.
When more than one field of the same name is executed in parallel, the
_selection set_ for each of the fields are merged together when completing the
value in order to continue execution of the sub-selection sets.

An example operation illustrating parallel fields with the same name with
sub-selections.
Expand Down
14 changes: 7 additions & 7 deletions spec/Section 7 -- Response.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,13 +294,13 @@ JSON format throughout this document.

### Serialized Map Ordering

Since the result of evaluating a selection set is ordered, the serialized Map of
results should preserve this order by writing the map entries in the same order
as those fields were requested as defined by selection set execution. Producing
a serialized response where fields are represented in the same order in which
they appear in the request improves human readability during debugging and
enables more efficient parsing of responses if the order of properties can be
anticipated.
Since the result of evaluating a _selection set_ is ordered, the serialized Map
of results should preserve this order by writing the map entries in the same
order as those fields were requested as defined by selection set execution.
Producing a serialized response where fields are represented in the same order
in which they appear in the request improves human readability during debugging
and enables more efficient parsing of responses if the order of properties can
be anticipated.

Serialization formats which represent an ordered map should preserve the order
of requested fields as defined by {CollectFields()} in the Execution section.
Expand Down

0 comments on commit b5ecff0

Please sign in to comment.