Skip to content

Commit a117f4e

Browse files
leebyronbenjie
andcommitted
Define 'execution' as in 'before execution begins'
Reintroduces #894 atop latest main Co-authored-by: Benjie <[email protected]>
1 parent 468d848 commit a117f4e

File tree

5 files changed

+83
-55
lines changed

5 files changed

+83
-55
lines changed

spec/Section 3 -- Type System.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ GraphQL supports two abstract types: interfaces and unions.
328328
An `Interface` defines a list of fields; `Object` types and other Interface
329329
types which implement this Interface are guaranteed to implement those fields.
330330
Whenever a field claims it will return an Interface type, it will return a valid
331-
implementing Object type during execution.
331+
implementing Object type during _execution_.
332332

333333
A `Union` defines a list of possible types; similar to interfaces, whenever the
334334
type system claims a union will be returned, one of the possible types will be
@@ -505,7 +505,7 @@ information on the serialization of scalars in common JSON and other formats.
505505
If a GraphQL service expects a scalar type as input to an argument, coercion is
506506
observable and the rules must be well defined. If an input value does not match
507507
a coercion rule, a _request error_ must be raised (input values are validated
508-
before execution begins).
508+
before _execution_ begins).
509509

510510
GraphQL has different constant literals to represent integer and floating-point
511511
input values, and coercion rules may apply differently depending on which type
@@ -810,7 +810,7 @@ And will yield the subset of each object type queried:
810810
**Field Ordering**
811811

812812
When querying an Object, the resulting mapping of fields are conceptually
813-
ordered in the same order in which they were encountered during execution,
813+
ordered in the same order in which they were encountered during _execution_,
814814
excluding fragments for which the type does not apply and fields or fragments
815815
that are skipped via `@skip` or `@include` directives. This ordering is
816816
correctly produced when using the {CollectFields()} algorithm.
@@ -2058,7 +2058,7 @@ directive @example on
20582058

20592059
Directives can also be used to annotate the type system definition language as
20602060
well, which can be a useful tool for supplying additional metadata in order to
2061-
generate GraphQL execution services, produce client generated runtime code, or
2061+
generate GraphQL services, produce client generated runtime code, or
20622062
many other useful extensions of the GraphQL semantics.
20632063

20642064
In this example, the directive `@example` annotates field and argument
@@ -2122,7 +2122,7 @@ directive @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
21222122
```
21232123

21242124
The `@skip` _built-in directive_ may be provided for fields, fragment spreads,
2125-
and inline fragments, and allows for conditional exclusion during execution as
2125+
and inline fragments, and allows for conditional exclusion during _execution_ as
21262126
described by the `if` argument.
21272127

21282128
In this example `experimentalField` will only be queried if the variable
@@ -2142,7 +2142,7 @@ directive @include(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
21422142

21432143
The `@include` _built-in directive_ may be provided for fields, fragment
21442144
spreads, and inline fragments, and allows for conditional inclusion during
2145-
execution as described by the `if` argument.
2145+
_execution_ as described by the `if` argument.
21462146

21472147
In this example `experimentalField` will only be queried if the variable
21482148
`$someTest` has the value `true`

spec/Section 4 -- Introspection.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ GraphQL supports type name introspection within any _selection set_ in an
7272
operation, with the single exception of selections at the root of a subscription
7373
operation. Type name introspection is accomplished via the meta-field
7474
`__typename: String!` on any Object, Interface, or Union. It returns the name of
75-
the concrete Object type at that point during execution.
75+
the concrete Object type at that point during _execution_.
7676

7777
This is most often used when querying against Interface or Union types to
7878
identify which actual Object type of the possible types has been returned.

spec/Section 5 -- Validation.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ given GraphQL schema.
77
An invalid request is still technically executable, and will always produce a
88
stable result as defined by the algorithms in the Execution section, however
99
that result may be ambiguous, surprising, or unexpected relative to a request
10-
containing validation errors, so execution should only occur for valid requests.
10+
containing validation errors, so _execution_ should only occur for valid requests.
1111

1212
Typically validation is performed in the context of a request immediately before
1313
execution, however a GraphQL service may execute a request without explicitly
@@ -108,7 +108,7 @@ input FindDogInput {
108108

109109
GraphQL execution will only consider the executable definitions Operation and
110110
Fragment. Type system definitions and extensions are not executable, and are not
111-
considered during execution.
111+
considered during _execution_.
112112

113113
To avoid ambiguity, a document containing {TypeSystemDefinitionOrExtension} is
114114
invalid for execution.
@@ -579,7 +579,7 @@ type that is either an Object, Interface or Union type.
579579
**Explanatory Text**
580580

581581
If multiple field selections with the same _response name_ are encountered
582-
during execution, the field and arguments to execute and the resulting value
582+
during _execution_, the field and arguments to execute and the resulting value
583583
should be unambiguous. Therefore any two field selections which might both be
584584
encountered for the same object are only valid if they are equivalent.
585585

spec/Section 6 -- Execution.md

Lines changed: 64 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ A GraphQL service generates a response from a request via execution.
1818
- {extensions} (optional): A map reserved for implementation-specific additional
1919
information.
2020

21-
Given this information, the result of {ExecuteRequest(schema, document,
21+
Given this information, the result of {Request(schema, document,
2222
operationName, variableValues, initialValue)} produces the response, to be
2323
formatted according to the Response section below.
2424

@@ -39,27 +39,45 @@ and have no effect on the observable execution, validation, or response of a
3939
GraphQL document. Descriptions and comments on executable documents MAY be used
4040
for non-observable purposes, such as logging and other developer tools.
4141

42-
## Executing Requests
42+
## Processing Requests
4343

44-
To execute a request, the executor must have a parsed {Document} and a selected
44+
<a name="#sec-Executing-Requests">
45+
<!-- Legacy link, this section was previously titled "Executing Requests" -->
46+
</a>
47+
48+
To process a request, the executor must have a parsed {Document} and a selected
4549
operation name to run if the document defines multiple operations, otherwise the
4650
document is expected to only contain a single operation. The result of the
47-
request is determined by the result of executing this operation according to the
48-
"Executing Operations” section below.
51+
request is determined by the result of performing this operation according to
52+
the "Performing Operations” section below.
53+
54+
The {Request()} algorithm contains the preamble for _execution_, handling
55+
concerns such as determining the operation and coercing the inputs, before
56+
passing the request on to the relevant algorithm for the operation's type which
57+
then performs any other necessary preliminary steps (for example establishing
58+
the source event stream for subscription operations) and then initiates
59+
_execution_.
60+
61+
Note: An error raised before _execution_ begins will typically be a _request
62+
error_, and once _execution_ begins will typically be an _execution error_.
4963

50-
ExecuteRequest(schema, document, operationName, variableValues, initialValue):
64+
:: We define _execution_ as the process of executing the operation's _root
65+
selection set_ through {ExecuteRootSelectionSet()}, and hence _execution_ begins
66+
when {ExecuteRootSelectionSet()} is called for the first time in a request.
67+
68+
Request(schema, document, operationName, variableValues, initialValue):
5169

5270
- Let {operation} be the result of {GetOperation(document, operationName)}.
5371
- Let {coercedVariableValues} be the result of {CoerceVariableValues(schema,
5472
operation, variableValues)}.
5573
- If {operation} is a query operation:
56-
- Return {ExecuteQuery(operation, schema, coercedVariableValues,
74+
- Return {Query(operation, schema, coercedVariableValues,
5775
initialValue)}.
5876
- Otherwise if {operation} is a mutation operation:
59-
- Return {ExecuteMutation(operation, schema, coercedVariableValues,
77+
- Return {Mutation(operation, schema, coercedVariableValues,
6078
initialValue)}.
6179
- Otherwise if {operation} is a subscription operation:
62-
- Return {Subscribe(operation, schema, coercedVariableValues, initialValue)}.
80+
- Return {Subscription(operation, schema, coercedVariableValues, initialValue)}.
6381

6482
GetOperation(document, operationName):
6583

@@ -74,27 +92,28 @@ GetOperation(document, operationName):
7492

7593
### Validating Requests
7694

77-
As explained in the Validation section, only requests which pass all validation
78-
rules should be executed. If validation errors are known, they should be
79-
reported in the list of "errors" in the response and the request must fail
80-
without execution.
95+
As explained in the Validation section, only operations from documents which
96+
pass all validation rules should be executed. If validation errors are known,
97+
they should be reported in the list of "errors" in the response and the request
98+
must fail without execution.
8199

82100
Typically validation is performed in the context of a request immediately before
83-
execution, however a GraphQL service may execute a request without immediately
84-
validating it if that exact same request is known to have been validated before.
85-
A GraphQL service should only execute requests which _at some point_ were known
86-
to be free of any validation errors, and have since not changed.
101+
calling {Request()}, however a GraphQL service may process a request without
102+
immediately validating the document if that exact same document is known to have
103+
been validated before. A GraphQL service should only execute operations which
104+
_at some point_ were known to be free of any validation errors, and have since
105+
not changed.
87106

88-
For example: the request may be validated during development, provided it does
89-
not later change, or a service may validate a request once and memoize the
90-
result to avoid validating the same request again in the future.
107+
For example: the document may be validated during development, provided it does
108+
not later change, or a service may validate a document once and memoize the
109+
result to avoid validating the same document again in the future.
91110

92111
### Coercing Variable Values
93112

94113
If the operation has defined any variables, then the values for those variables
95114
need to be coerced using the input coercion rules of variable's declared type.
96115
If a _request error_ is encountered during input coercion of variable values,
97-
then the operation fails without execution.
116+
then the request fails without _execution_.
98117

99118
CoerceVariableValues(schema, operation, variableValues):
100119

@@ -131,7 +150,11 @@ CoerceVariableValues(schema, operation, variableValues):
131150

132151
Note: This algorithm is very similar to {CoerceArgumentValues()}.
133152

134-
## Executing Operations
153+
## Performing Operations
154+
155+
<a name="#sec-Executing-Operations">
156+
<!-- Legacy link, this section was previously titled "Executing Operations" -->
157+
</a>
135158

136159
The type system, as described in the "Type System" section of the spec, must
137160
provide a query root operation type. If mutations or subscriptions are
@@ -144,9 +167,9 @@ If the operation is a query, the result of the operation is the result of
144167
executing the operation’s _root selection set_ with the query root operation
145168
type.
146169

147-
An initial value may be provided when executing a query operation.
170+
An initial value may be provided when perfoming a query operation.
148171

149-
ExecuteQuery(query, schema, variableValues, initialValue):
172+
Query(query, schema, variableValues, initialValue):
150173

151174
- Let {queryType} be the root Query type in {schema}.
152175
- Assert: {queryType} is an Object type.
@@ -164,7 +187,7 @@ It is expected that the top level fields in a mutation operation perform
164187
side-effects on the underlying data system. Serial execution of the provided
165188
mutations ensures against race conditions during these side-effects.
166189

167-
ExecuteMutation(mutation, schema, variableValues, initialValue):
190+
Mutation(mutation, schema, variableValues, initialValue):
168191

169192
- Let {mutationType} be the root Mutation type in {schema}.
170193
- Assert: {mutationType} is an Object type.
@@ -176,12 +199,13 @@ ExecuteMutation(mutation, schema, variableValues, initialValue):
176199

177200
If the operation is a subscription, the result is an _event stream_ called the
178201
_response stream_ where each event in the event stream is the result of
179-
executing the operation for each new event on an underlying _source stream_.
202+
executing the operation’s _root selection set_ for each new event on an
203+
underlying _source stream_.
180204

181-
Executing a subscription operation creates a persistent function on the service
205+
Perfoming a subscription operation creates a persistent function on the service
182206
that maps an underlying _source stream_ to a returned _response stream_.
183207

184-
Subscribe(subscription, schema, variableValues, initialValue):
208+
Subscription(subscription, schema, variableValues, initialValue):
185209

186210
- Let {sourceStream} be the result of running
187211
{CreateSourceEventStream(subscription, schema, variableValues, initialValue)}.
@@ -190,8 +214,8 @@ Subscribe(subscription, schema, variableValues, initialValue):
190214
variableValues)}.
191215
- Return {responseStream}.
192216

193-
Note: In a large-scale subscription system, the {Subscribe()} and
194-
{ExecuteSubscriptionEvent()} algorithms may be run on separate services to
217+
Note: In a large-scale subscription system, the {Subscription()} and
218+
{SubscriptionEvent()} algorithms may be run on separate services to
195219
maintain predictable scaling properties. See the section below on Supporting
196220
Subscriptions at Scale.
197221

@@ -313,7 +337,7 @@ MapSourceToResponseEvent(sourceStream, subscription, schema, variableValues):
313337
- Let {responseStream} be a new _event stream_.
314338
- When {sourceStream} emits {sourceValue}:
315339
- Let {executionResult} be the result of running
316-
{ExecuteSubscriptionEvent(subscription, schema, variableValues,
340+
{SubscriptionEvent(subscription, schema, variableValues,
317341
sourceValue)}.
318342
- If internal {error} was raised:
319343
- Cancel {sourceStream}.
@@ -328,21 +352,21 @@ MapSourceToResponseEvent(sourceStream, subscription, schema, variableValues):
328352
- Complete {responseStream} normally.
329353
- Return {responseStream}.
330354

331-
Note: Since {ExecuteSubscriptionEvent()} handles all _execution error_, and
355+
Note: Since {SubscriptionEvent()} handles all _execution error_, and
332356
_request error_ only occur during {CreateSourceEventStream()}, the only
333-
remaining error condition handled from {ExecuteSubscriptionEvent()} are internal
357+
remaining error condition handled from {SubscriptionEvent()} are internal
334358
exceptional errors not described by this specification.
335359

336-
ExecuteSubscriptionEvent(subscription, schema, variableValues, initialValue):
360+
SubscriptionEvent(subscription, schema, variableValues, initialValue):
337361

338362
- Let {subscriptionType} be the root Subscription type in {schema}.
339363
- Assert: {subscriptionType} is an Object type.
340364
- Let {rootSelectionSet} be the _root selection set_ in {subscription}.
341365
- Return {ExecuteRootSelectionSet(variableValues, initialValue,
342366
subscriptionType, rootSelectionSet, "normal")}.
343367

344-
Note: The {ExecuteSubscriptionEvent()} algorithm is intentionally similar to
345-
{ExecuteQuery()} since this is how each event result is produced.
368+
Note: The {SubscriptionEvent()} algorithm is intentionally similar to
369+
{Query()} since this is how each event result is produced.
346370

347371
#### Unsubscribe
348372

@@ -638,7 +662,7 @@ A valid GraphQL executor can resolve the four fields in whatever order it chose
638662
(however of course `birthday` must be resolved before `month`, and `address`
639663
before `street`).
640664

641-
When executing a mutation, the selections in the top most selection set will be
665+
When perfoming a mutation, the selections in the top most selection set will be
642666
executed in serial order, starting with the first appearing field textually.
643667

644668
When executing a collected fields map serially, the executor must consider each
@@ -788,9 +812,9 @@ CoerceArgumentValues(objectType, field, variableValues):
788812
Any _request error_ raised as a result of input coercion during
789813
{CoerceArgumentValues()} should be treated instead as an _execution error_.
790814

791-
Note: Variable values are not coerced because they are expected to be coerced
792-
before executing the operation in {CoerceVariableValues()}, and valid operations
793-
must only allow usage of variables of appropriate types.
815+
Note: Variable values are not coerced because they are expected to be coerced by
816+
{CoerceVariableValues()} before _execution_ begins, and valid operations must
817+
only allow usage of variables of appropriate types.
794818

795819
Note: Implementations are encouraged to optimize the coercion of an argument's
796820
default value by doing so only once and caching the resulting coerced value.

spec/Section 7 -- Response.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ An _execution result_ must be map.
2424
The _execution result_ must contain an entry with key {"data"}. The value of
2525
this entry is described in the "Data" section.
2626

27-
If execution raised any errors, the _execution result_ must contain an entry
27+
If any errors are raised during _execution_, the _execution result_ must contain an entry
2828
with key {"errors"}. The value of this entry must be a non-empty list of
2929
_execution error_ raised during execution. Each error must be a map as described
3030
in the "Errors" section below. If the request completed without raising any
@@ -115,20 +115,24 @@ found at `["hero", "friends"]`, the hero's first friend at
115115

116116
### Data
117117

118-
The {"data"} entry in the _execution result_ will be the result of the execution
118+
The {"data"} entry in the _execution result_ will be the result of the _execution_
119119
of the requested operation. If the operation was a query, this output will be an
120120
object of the query root operation type; if the operation was a mutation, this
121121
output will be an object of the mutation root operation type.
122122

123123
The response data is the result of accumulating the resolved result of all
124124
response positions during execution.
125125

126-
If an error was raised before execution begins, the _response_ must be a
126+
If an error was raised before _execution_ begins, the _response_ must be a
127127
_request error result_ which will result in no response data.
128128

129-
If an error was raised during the execution that prevented a valid response, the
129+
If an error was raised during _execution_ that prevented a valid response, the
130130
{"data"} entry in the response should be `null`.
131131

132+
Note: Request errors (including those raised during {Request()}) occur
133+
before _execution_ begins; when a request error is raised the {"data"} entry
134+
should not be present in the result.
135+
132136
### Errors
133137

134138
The {"errors"} entry in the _execution result_ or _request error result_ is a
@@ -138,7 +142,7 @@ of data described by the error result format below.
138142
**Request Errors**
139143

140144
:: A _request error_ is an error raised during a _request_ which results in no
141-
response data. Typically raised before execution begins, a request error may
145+
response data. Typically raised before _execution_ begins, a request error may
142146
occur due to a parse grammar or validation error in the _Document_, an inability
143147
to determine which operation to execute, or invalid input values for variables.
144148

0 commit comments

Comments
 (0)