From 970d4348eb9fc11bc257ba077a976afed9a7beb4 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 8 May 2025 19:59:49 +0100 Subject: [PATCH 1/5] Use 203 as the partial status code --- spec/GraphQLOverHTTP.md | 47 +++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/spec/GraphQLOverHTTP.md b/spec/GraphQLOverHTTP.md index 4954bda5..c2705e24 100644 --- a/spec/GraphQLOverHTTP.md +++ b/spec/GraphQLOverHTTP.md @@ -651,28 +651,38 @@ This section only applies when the response body is to use the `application/graphql-response+json` media type. If the _GraphQL response_ contains the {data} entry and it is not {null}, then -the server MUST reply with a `2xx` status code and SHOULD reply with `200` -status code. +the server MUST reply with a `2xx` status code. + +If the _GraphQL response_ contains the {data} entry and does not contain the +{errors} entry, then the server SHOULD reply with `200` status code. + +Note: There are no circumstances where the GraphQL specification allows for a +response having {data} as {null} without {errors} being present. + +If the _GraphQL response_ contains both the {data} entry (even if it is {null}) +and the {errors} entry, then the server SHOULD reply with `203` status code. Note: The result of executing a GraphQL operation may contain partial data as well as encountered errors. Errors that happen during execution of the GraphQL operation typically become part of the result, as long as the server is still able to produce a well-formed _GraphQL response_. There's currently not an -approved HTTP status code to use for a "partial response," contenders include -WebDAV's status code "207 Multi-Status" and using a custom code such as "247 -Partial Success." +approved official HTTP status code to use for a "partial success," contenders +include "206 Partial Content" (which requires the `Range` header), WebDAV's +status code "207 Multi-Status", and using a custom code such as "294 Partial +Success." [IETF RFC2616 Section 6.1.1](https://datatracker.ietf.org/doc/html/rfc2616#section-6.1.1) states "codes are fully defined in section 10" implying that though more codes are expected to be supported over time, valid codes must be present in this -document. - -If the _GraphQL response_ contains the {data} entry and it is {null}, then the -server SHOULD reply with a `2xx` status code and it is RECOMMENDED it replies -with `200` status code. - -Note: Using `4xx` and `5xx` status codes in this situation is not recommended - -since no _GraphQL request error_ has occurred it is seen as a "partial -response". +document. For compatibility reasons, using `203` seems to work the best with +intermediate servers and clients. We hope to one day move to `294` if someone +can push it through the IETF review process. Using `4xx` and `5xx` status codes +in this situation is not appropriate - since no _GraphQL request error_ has +occurred it is seen as a "partial response" or "partial success". Note that this +use of HTTP 203 does not strictly align with the intended semantics of this +status code, but was a pragmatic choice to maximize compatibility whilst +allowing servers to indicate partial success such that intermediaries that do +not implement this specification may still track the not-fully-successful +request (for example, for anomaly detection). If the _GraphQL response_ does not contain the {data} entry then the server MUST reply with a `4xx` or `5xx` status code as appropriate. @@ -693,6 +703,15 @@ regardless of the status code. Intermediary servers may use the status code to determine the status of the _GraphQL response_ without needing to process the response body. +A client should process a GraphQL response that uses the +`application/graphql-response+json` media type independent of which HTTP status +code it uses, instead reading the response body to determine how to handle the +request. + +Note: For the avoidance of doubt, GraphQL clients, once they have established +that the response uses `application/graphql-response+json`, should completely +ignore the HTTP status code. + #### Examples The following examples provide guidance on how to deal with specific error cases From 05182f557ef8db2578e136903f50e435b185dbc1 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 8 May 2025 20:17:49 +0100 Subject: [PATCH 2/5] Overhaul massive inline note by moving much to section 7 --- spec/GraphQLOverHTTP.md | 84 ++++++++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 34 deletions(-) diff --git a/spec/GraphQLOverHTTP.md b/spec/GraphQLOverHTTP.md index c2705e24..f37ccd44 100644 --- a/spec/GraphQLOverHTTP.md +++ b/spec/GraphQLOverHTTP.md @@ -647,9 +647,21 @@ should be added to the above. ### application/graphql-response+json -This section only applies when the response body is to use the +This section only applies when the response body uses the `application/graphql-response+json` media type. +With this media type, clients should process the response as a well-formed +_GraphQL response_ independent of the HTTP status code, and should read the +response body (specifically {data} and {errors}) to determine the status of the +response. + +Note: The purpose of setting a status code is to aid intermediary services and +tooling (which may not implement this specification) in understanding the rough +status of a response. This is useful in request logs, anomaly and intrusion +detection, metrics and observability, API gateways, and more. The status code is +not intended to aid the client, in fact it is recommended the client ignore the +status code when this media type is in use. + If the _GraphQL response_ contains the {data} entry and it is not {null}, then the server MUST reply with a `2xx` status code. @@ -665,24 +677,11 @@ and the {errors} entry, then the server SHOULD reply with `203` status code. Note: The result of executing a GraphQL operation may contain partial data as well as encountered errors. Errors that happen during execution of the GraphQL operation typically become part of the result, as long as the server is still -able to produce a well-formed _GraphQL response_. There's currently not an -approved official HTTP status code to use for a "partial success," contenders -include "206 Partial Content" (which requires the `Range` header), WebDAV's -status code "207 Multi-Status", and using a custom code such as "294 Partial -Success." -[IETF RFC2616 Section 6.1.1](https://datatracker.ietf.org/doc/html/rfc2616#section-6.1.1) -states "codes are fully defined in section 10" implying that though more codes -are expected to be supported over time, valid codes must be present in this -document. For compatibility reasons, using `203` seems to work the best with -intermediate servers and clients. We hope to one day move to `294` if someone -can push it through the IETF review process. Using `4xx` and `5xx` status codes -in this situation is not appropriate - since no _GraphQL request error_ has -occurred it is seen as a "partial response" or "partial success". Note that this -use of HTTP 203 does not strictly align with the intended semantics of this -status code, but was a pragmatic choice to maximize compatibility whilst -allowing servers to indicate partial success such that intermediaries that do -not implement this specification may still track the not-fully-successful -request (for example, for anomaly detection). +able to produce a well-formed _GraphQL response_. For details of why status code +`203` is recommended, see [Partial success](#sec-Partial-success). Using `4xx` +and `5xx` status codes in this situation is not appropriate - since no _GraphQL +request error_ has occurred it is seen as a "partial response" or "partial +success". If the _GraphQL response_ does not contain the {data} entry then the server MUST reply with a `4xx` or `5xx` status code as appropriate. @@ -697,21 +696,6 @@ pass validation, then the server SHOULD reply with `400` status code. If the client is not permitted to issue the GraphQL request then the server SHOULD reply with `403`, `401` or similar appropriate status code. -Note: When the response media type is `application/graphql-response+json`, -clients can rely on the response being a well-formed _GraphQL response_ -regardless of the status code. Intermediary servers may use the status code to -determine the status of the _GraphQL response_ without needing to process the -response body. - -A client should process a GraphQL response that uses the -`application/graphql-response+json` media type independent of which HTTP status -code it uses, instead reading the response body to determine how to handle the -request. - -Note: For the avoidance of doubt, GraphQL clients, once they have established -that the response uses `application/graphql-response+json`, should completely -ignore the HTTP status code. - #### Examples The following examples provide guidance on how to deal with specific error cases @@ -801,6 +785,38 @@ is met: - the response media type is `application/graphql-response+json`, or - the status code is `200`. +## Partial success + +The result of executing a GraphQL operation may contain partial data as well as +encountered errors. Errors that happen during execution of the GraphQL operation +typically become part of the result, as long as the server is still able to +produce a well-formed _GraphQL response_. + +Using `4xx` and `5xx` status codes when {data} is present and non-null is not +appropriate; since no _GraphQL request error_ has occurred it is seen as a +"partial response" or "partial success". + +There's currently not an approved official HTTP status code to use for a +"partial success," contenders include "206 Partial Content" (which requires the +`Range` header), WebDAV's status code "207 Multi-Status", and using a custom +code such as "294 Partial Success." + +[IETF RFC2616 Section 6.1.1](https://datatracker.ietf.org/doc/html/rfc2616#section-6.1.1) +states "codes are fully defined in section 10" implying that though more codes +are expected to be supported over time, valid codes must be present in this +document. For compatibility reasons, using HTTP status `203` which has no +additional requirements seems to work the best with intermediate servers and +clients, but since it does not semantically line up we only recommend its usage +alongside the `application/graphql-response+json` media type which makes the +meaning explicit. We hope to one day move to `294` if someone can push it +through the IETF review process. + +Note that this use of HTTP 203 does not strictly align with the intended +semantics of this status code, but was a pragmatic choice to maximize +compatibility whilst allowing servers to indicate partial success such that +intermediaries that do not implement this specification may still track the +not-fully-successful request (for example, for observability). + ## Security This specification focuses solely on the intersection of GraphQL and HTTP. From 313cebd117a08dd2ea964e1a4a1a0fa2d646b53b Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 8 May 2025 20:21:56 +0100 Subject: [PATCH 3/5] spec-md formatting --- spec/GraphQLOverHTTP.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/GraphQLOverHTTP.md b/spec/GraphQLOverHTTP.md index f37ccd44..c90c6381 100644 --- a/spec/GraphQLOverHTTP.md +++ b/spec/GraphQLOverHTTP.md @@ -811,11 +811,11 @@ alongside the `application/graphql-response+json` media type which makes the meaning explicit. We hope to one day move to `294` if someone can push it through the IETF review process. -Note that this use of HTTP 203 does not strictly align with the intended -semantics of this status code, but was a pragmatic choice to maximize -compatibility whilst allowing servers to indicate partial success such that -intermediaries that do not implement this specification may still track the -not-fully-successful request (for example, for observability). +Note: This use of HTTP 203 does not strictly align with the intended semantics +of this status code, but was a pragmatic choice to maximize compatibility whilst +allowing servers to indicate partial success such that intermediaries that do +not implement this specification may still track the not-fully-successful +request (for example, for observability). ## Security From f2552ac8d91668293f2f07c146bc880da1689b1c Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Mon, 2 Jun 2025 17:30:34 +0100 Subject: [PATCH 4/5] Replace 203 status code with 294 --- spec/GraphQLOverHTTP.md | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/spec/GraphQLOverHTTP.md b/spec/GraphQLOverHTTP.md index c90c6381..b752c1ba 100644 --- a/spec/GraphQLOverHTTP.md +++ b/spec/GraphQLOverHTTP.md @@ -672,13 +672,13 @@ Note: There are no circumstances where the GraphQL specification allows for a response having {data} as {null} without {errors} being present. If the _GraphQL response_ contains both the {data} entry (even if it is {null}) -and the {errors} entry, then the server SHOULD reply with `203` status code. +and the {errors} entry, then the server SHOULD reply with `294` status code. Note: The result of executing a GraphQL operation may contain partial data as well as encountered errors. Errors that happen during execution of the GraphQL operation typically become part of the result, as long as the server is still able to produce a well-formed _GraphQL response_. For details of why status code -`203` is recommended, see [Partial success](#sec-Partial-success). Using `4xx` +`294` is recommended, see [Partial success](#sec-Partial-success). Using `4xx` and `5xx` status codes in this situation is not appropriate - since no _GraphQL request error_ has occurred it is seen as a "partial response" or "partial success". @@ -797,23 +797,18 @@ appropriate; since no _GraphQL request error_ has occurred it is seen as a "partial response" or "partial success". There's currently not an approved official HTTP status code to use for a -"partial success," contenders include "206 Partial Content" (which requires the -`Range` header), WebDAV's status code "207 Multi-Status", and using a custom -code such as "294 Partial Success." - -[IETF RFC2616 Section 6.1.1](https://datatracker.ietf.org/doc/html/rfc2616#section-6.1.1) -states "codes are fully defined in section 10" implying that though more codes -are expected to be supported over time, valid codes must be present in this -document. For compatibility reasons, using HTTP status `203` which has no -additional requirements seems to work the best with intermediate servers and -clients, but since it does not semantically line up we only recommend its usage -alongside the `application/graphql-response+json` media type which makes the -meaning explicit. We hope to one day move to `294` if someone can push it -through the IETF review process. - -Note: This use of HTTP 203 does not strictly align with the intended semantics -of this status code, but was a pragmatic choice to maximize compatibility whilst -allowing servers to indicate partial success such that intermediaries that do +"partial success". Contenders include "203 Non-Authorative information" (which +indicates the response has been transformed), "206 Partial Content" (which +requires the `Range` header), and WebDAV's status code "207 Multi-Status" (which +"provides status for multiple _independent_ operations"). None of those quite +fit GraphQL's needs, so we recommend using custom code "294 Partial Success". +Since we are defining the code ourselves, rather than the IETF, we only +recommend its usage alongside the `application/graphql-response+json` media type +which makes the meaning explicit. + +Note: This status code is not to help clients, who should ignore the status code +of a response when receiving the `application/graphql-response+json` media type, +but allows servers to indicate partial success such that intermediaries that do not implement this specification may still track the not-fully-successful request (for example, for observability). From 8beaddff6acbb74cfb89be04179de9cb57982441 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Mon, 2 Jun 2025 17:35:45 +0100 Subject: [PATCH 5/5] Typo --- spec/GraphQLOverHTTP.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/GraphQLOverHTTP.md b/spec/GraphQLOverHTTP.md index b752c1ba..c99f39ca 100644 --- a/spec/GraphQLOverHTTP.md +++ b/spec/GraphQLOverHTTP.md @@ -797,7 +797,7 @@ appropriate; since no _GraphQL request error_ has occurred it is seen as a "partial response" or "partial success". There's currently not an approved official HTTP status code to use for a -"partial success". Contenders include "203 Non-Authorative information" (which +"partial success". Contenders include "203 Non-Authoritative information" (which indicates the response has been transformed), "206 Partial Content" (which requires the `Range` header), and WebDAV's status code "207 Multi-Status" (which "provides status for multiple _independent_ operations"). None of those quite