diff --git a/spec/Section 6 -- Execution.md b/spec/Section 6 -- Execution.md index f3e080705..f9b16107c 100644 --- a/spec/Section 6 -- Execution.md +++ b/spec/Section 6 -- Execution.md @@ -310,13 +310,13 @@ MapSourceToResponseEvent(sourceStream, subscription, schema, variableValues): - Let {responseStream} be a new _event stream_. - When {sourceStream} emits {sourceValue}: - - Let {response} be the result of running + - Let {executionResult} be the result of running {ExecuteSubscriptionEvent(subscription, schema, variableValues, sourceValue)}. - If internal {error} was raised: - Cancel {sourceStream}. - Complete {responseStream} with {error}. - - Otherwise emit {response} on {responseStream}. + - Otherwise emit {executionResult} on {responseStream}. - When {sourceStream} completes normally: - Complete {responseStream} normally. - When {sourceStream} completes with {error}: @@ -827,23 +827,24 @@ or coercion, at a specific _response position_. While these errors must be reported in the response, they are "handled" by producing partial {"data"} in the _response_. -Note: This is distinct from a _request error_ which results in a response with -no data. +Note: This is distinct from a _request error_ which results in a _request error +result_ with no data. If an execution error is raised while resolving a field (either directly or nested inside any lists), it is handled as though the _response position_ at which the error occurred resolved to {null}, and the error must be added to the -{"errors"} list in the response. +{"errors"} list in the _execution result_. If the result of resolving a _response position_ is {null} (either due to the result of {ResolveFieldValue()} or because an execution error was raised), and that position is of a `Non-Null` type, then an execution error is raised at that -position. The error must be added to the {"errors"} list in the response. +position. The error must be added to the {"errors"} list in the _execution +result_. If a _response position_ resolves to {null} because of an execution error which -has already been added to the {"errors"} list in the response, the {"errors"} -list must not be further affected. That is, only one error should be added to -the errors list per _response position_. +has already been added to the {"errors"} list in the _execution result_, the +{"errors"} list must not be further affected. That is, only one error should be +added to the errors list per _response position_. Since `Non-Null` response positions cannot be {null}, execution errors are propagated to be handled by the parent _response position_. If the parent @@ -857,5 +858,5 @@ position_ must resolve to {null}. If the `List` type is also wrapped in a `Non-Null`, the execution error continues to propagate upwards. If every _response position_ from the root of the request to the source of the -execution error has a `Non-Null` type, then the {"data"} entry in the response -should be {null}. +execution error has a `Non-Null` type, then the {"data"} entry in the _execution +result_ should be {null}. diff --git a/spec/Section 7 -- Response.md b/spec/Section 7 -- Response.md index 037b2a167..f79100cd2 100644 --- a/spec/Section 7 -- Response.md +++ b/spec/Section 7 -- Response.md @@ -9,40 +9,66 @@ the case that any _execution error_ was raised and replaced with {null}. ## Response Format -A GraphQL request returns either a _response_ or a _response stream_. +:: A GraphQL request returns a _response_. A _response_ is either an _execution +result_, a _response stream_, or a _request error result_. -### Response +### Execution Result -:: A GraphQL request returns a _response_ when the GraphQL operation is a query -or mutation. A _response_ must be a map. +:: A GraphQL request returns an _execution result_ when the GraphQL operation is +a query or mutation and the request included execution. Additionally, for each +event in a subscription's _source stream_, the _response stream_ will emit an +_execution result_. -If the request raised any errors, the response map must contain an entry with -key {"errors"}. The value of this entry is described in the "Errors" section. If -the request completed without raising any errors, this entry must not be -present. +An _execution result_ must be map. -If the request included execution, the response map must contain an entry with -key {"data"}. The value of this entry is described in the "Data" section. If the -request failed before execution, due to a syntax error, missing information, or -validation error, this entry must not be present. +The _execution result_ must contain an entry with key {"data"}. The value of +this entry is described in the "Data" section. -The response map may also contain an entry with key `extensions`. This entry, if -set, must have a map as its value. This entry is reserved for implementers to -extend the protocol however they see fit, and hence there are no additional -restrictions on its contents. +If execution raised any errors, the _execution result_ must contain an entry +with key {"errors"}. The value of this entry must be a non-empty list of +_execution error_ raised during execution. Each error must be a map as described +in the "Errors" section below. If the request completed without raising any +errors, this entry must not be present. -To ensure future changes to the protocol do not break existing services and -clients, the top level response map must not contain any entries other than the -three described above. +Note: When {"errors"} is present in a _execution result_, it may be helpful for +it to appear first when serialized to make it more apparent that errors are +present. -Note: When {"errors"} is present in the response, it may be helpful for it to -appear first when serialized to make it more clear when errors are present in a -response during debugging. +The _execution result_ may also contain an entry with key `extensions`. The +value of this entry is described in the "Extensions" section. ### Response Stream :: A GraphQL request returns a _response stream_ when the GraphQL operation is a -subscription. A _response stream_ must be a stream of _response_. +subscription and the request included execution. A response stream must be a +stream of _execution result_. + +### Request Error Result + +:: A GraphQL request returns a _request error result_ when one or more _request +error_ are raised, causing the request to fail before execution. This request +will result in no response data. + +Note: A _request error_ may be raised before execution due to missing +information, syntax errors, validation failure, coercion failure, or any other +reason the implementation may determine should prevent the request from +proceeding. + +A _request error result_ must be a map. + +The _request error result_ map must contain an entry with key {"errors"}. The +value of this entry must be a non-empty list of _request error_ raised during +the _request_. It must contain at least one _request error_ indicating why no +data was able to be returned. Each error must be a map as described in the +"Errors" section below. + +Note: It may be helpful for the {"errors"} key to appear first when serialized +to make it more apparent that errors are present. + +The _request error result_ map must not contain an entry with key {"data"}. + +The _request error result_ map may also contain an entry with key `extensions`. +The value of this entry is described in the "Extensions" section. ### Response Position @@ -89,37 +115,25 @@ found at `["hero", "friends"]`, the hero's first friend at ### Data -The {"data"} entry in the response will be the result of the execution of the -requested operation. If the operation was a query, this output will be an object -of the query root operation type; if the operation was a mutation, this output -will be an object of the mutation root operation type. +The {"data"} entry in the _execution result_ will be the result of the execution +of the requested operation. If the operation was a query, this output will be an +object of the query root operation type; if the operation was a mutation, this +output will be an object of the mutation root operation type. The response data is the result of accumulating the resolved result of all response positions during execution. -If an error was raised before execution begins, the {"data"} entry should not be -present in the response. +If an error was raised before execution begins, the _response_ must be a +_request error result_ which will result in no response data. If an error was raised during the execution that prevented a valid response, the {"data"} entry in the response should be `null`. ### Errors -The {"errors"} entry in the response is a non-empty list of errors raised during -the _request_, where each error is a map of data described by the error result -format below. - -If present, the {"errors"} entry in the response must contain at least one -error. If no errors were raised during the request, the {"errors"} entry must -not be present in the response. - -If the {"data"} entry in the response is not present, the {"errors"} entry must -be present. It must contain at least one _request error_ indicating why no data -was able to be returned. - -If the {"data"} entry in the response is present (including if it is the value -{null}), the {"errors"} entry must be present if and only if one or more -_execution error_ was raised during execution. +The {"errors"} entry in the _execution result_ or _request error result_ is a +non-empty list of errors raised during the _request_, where each error is a map +of data described by the error result format below. **Request Errors** @@ -130,9 +144,9 @@ to determine which operation to execute, or invalid input values for variables. A request error is typically the fault of the requesting client. -If a request error is raised, the {"data"} entry in the response must not be -present, the {"errors"} entry must include the error, and request execution -should be halted. +If a request error is raised, the _response_ must be a _request error result_. +The {"data"} entry in this map must not be present, the {"errors"} entry must +include the error, and request execution should be halted. **Execution Errors** @@ -307,6 +321,20 @@ discouraged. } ``` +### Extensions + +The {"extensions"} entry in an _execution result_ or _request error result_, if +set, must have a map as its value. This entry is reserved for implementers to +extend the protocol however they see fit, and hence there are no additional +restrictions on its contents. + +### Additional Entries + +To ensure future changes to the protocol do not break existing services and +clients, the _execution result_ and _request error result_ maps must not contain +any entries other than those described above. Clients must ignore any entries +other than those described above. + ## Serialization Format GraphQL does not require a specific serialization format. However, clients