From 133f612c70404a8fee776f7b7eb73872469a3395 Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Sat, 27 Jul 2024 17:15:26 +0200 Subject: [PATCH 01/13] Clarify server vs intermediary service --- spec/GraphQLOverHTTP.md | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/spec/GraphQLOverHTTP.md b/spec/GraphQLOverHTTP.md index e1b40e7e..8be0a915 100644 --- a/spec/GraphQLOverHTTP.md +++ b/spec/GraphQLOverHTTP.md @@ -511,19 +511,16 @@ execution regardless of validation errors. ## Status Codes -In case of errors that completely prevent the generation of a well-formed -_GraphQL response_, the server SHOULD respond with the appropriate status code -depending on the concrete error condition, and MUST NOT respond with a `2xx` -status code when using the `application/graphql-response+json` media type. +The status codes depends on the media type with which the GraphQL response will +be served. -Note: Typically the appropriate status code will be `400` (Bad Request). - -Note: This rule is "should" to maintain compatibility with legacy servers which -can return 200 status codes even when this type of error occurs, but only when -not using the `application/graphql-response+json` media type. - -Otherwise, the status codes depends on the media type with which the GraphQL -response will be served: +Note: when using the `application/graphql-response+json` media type, the status +code is primarily aimed for intermediary servers that do not understand GraphQL. +In these cases, clients can rely on the response being a well-formed _GraphQL +response_ regardless of the status code. When using the `application/json` media +type on the other hand, clients may use a `2xx` status code as an indication +that the body contains a well-formed _GraphQL response_. See +[processing a response](#sec-Processing-a-response) for more details. ### application/json @@ -738,10 +735,15 @@ Note: The GraphQL specification and refers to the situation wherein a _GraphQL field error_ occurs as a partial response; it still indicates successful execution. -## Processing the response +## Processing a response + +In a typical environment, the source of a response may be some intermediary +server such as an API gateway, a proxy, a firewall, etc. + +Those intermediary servers may not understand GraphQL: in the case of an error, +they may return their own non-GraphQL `application/json` response with a +non-`2xx` status code. -If the response uses a non-`200` status code and the media type of the response -payload is `application/json` then the client MUST NOT rely on the body to be a -well-formed _GraphQL response_ since the source of the response may not be the -server but instead some intermediary such as API gateways, proxies, firewalls, -etc. +For this reason, if the response uses a non-`2xx` status code and the media type +of the response body is `application/json` then the client MUST NOT rely on the +body to be a well-formed _GraphQL response_. From 55f79bb0629bacd14178d5053e034f3e6bbfbd56 Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Sat, 27 Jul 2024 18:06:42 +0200 Subject: [PATCH 02/13] Update spec/GraphQLOverHTTP.md Co-authored-by: Shane Krueger --- spec/GraphQLOverHTTP.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/GraphQLOverHTTP.md b/spec/GraphQLOverHTTP.md index 8be0a915..8782f2d8 100644 --- a/spec/GraphQLOverHTTP.md +++ b/spec/GraphQLOverHTTP.md @@ -737,8 +737,8 @@ response; it still indicates successful execution. ## Processing a response -In a typical environment, the source of a response may be some intermediary -server such as an API gateway, a proxy, a firewall, etc. +The source of a response may be an intermediary server, such as an API gateway, proxy, or +firewall, in certain environments. Those intermediary servers may not understand GraphQL: in the case of an error, they may return their own non-GraphQL `application/json` response with a From 86819115b6eef6b98d1dfdf4f26fa04b6c379c14 Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Sat, 27 Jul 2024 18:27:33 +0200 Subject: [PATCH 03/13] Feedbacks: - split the note in 2 - be explicit about response media type --- spec/GraphQLOverHTTP.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/spec/GraphQLOverHTTP.md b/spec/GraphQLOverHTTP.md index 8782f2d8..38be9aca 100644 --- a/spec/GraphQLOverHTTP.md +++ b/spec/GraphQLOverHTTP.md @@ -512,15 +512,7 @@ execution regardless of validation errors. ## Status Codes The status codes depends on the media type with which the GraphQL response will -be served. - -Note: when using the `application/graphql-response+json` media type, the status -code is primarily aimed for intermediary servers that do not understand GraphQL. -In these cases, clients can rely on the response being a well-formed _GraphQL -response_ regardless of the status code. When using the `application/json` media -type on the other hand, clients may use a `2xx` status code as an indication -that the body contains a well-formed _GraphQL response_. See -[processing a response](#sec-Processing-a-response) for more details. +be served: ### application/json @@ -565,6 +557,11 @@ of `2xx` or `5xx` status codes when responding to invalid requests using the Note: URLs that enable GraphQL requests may enable other types of requests - see the [URL](#url) section. +Note: When the response media type is `application/json`, clients may use a +`2xx` status code as an indication that the body contains a well-formed _GraphQL +response_. See [processing a response](#sec-Processing-a-response) for more +details. + #### Examples The following examples provide guidance on how to deal with specific error cases @@ -668,6 +665,12 @@ 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. The intermediary servers that do not understand +GraphQL may use the status code to get some information about the shape of the +_GraphQL response_. + #### Examples The following examples provide guidance on how to deal with specific error cases From 4d6d3d95376f9e4f377e2cb648bca4cdfeff34f9 Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Sat, 27 Jul 2024 18:33:17 +0200 Subject: [PATCH 04/13] format --- spec/GraphQLOverHTTP.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/GraphQLOverHTTP.md b/spec/GraphQLOverHTTP.md index 38be9aca..a2dacf06 100644 --- a/spec/GraphQLOverHTTP.md +++ b/spec/GraphQLOverHTTP.md @@ -740,8 +740,8 @@ response; it still indicates successful execution. ## Processing a response -The source of a response may be an intermediary server, such as an API gateway, proxy, or -firewall, in certain environments. +The source of a response may be an intermediary server, such as an API gateway, +proxy, or firewall, in certain environments. Those intermediary servers may not understand GraphQL: in the case of an error, they may return their own non-GraphQL `application/json` response with a From 443157439e5ddc1c7013f4a7a39ead67d158a3b8 Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Sat, 27 Jul 2024 19:09:51 +0200 Subject: [PATCH 05/13] Update spec/GraphQLOverHTTP.md Co-authored-by: Shane Krueger --- spec/GraphQLOverHTTP.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/spec/GraphQLOverHTTP.md b/spec/GraphQLOverHTTP.md index a2dacf06..62cb4643 100644 --- a/spec/GraphQLOverHTTP.md +++ b/spec/GraphQLOverHTTP.md @@ -557,10 +557,9 @@ of `2xx` or `5xx` status codes when responding to invalid requests using the Note: URLs that enable GraphQL requests may enable other types of requests - see the [URL](#url) section. -Note: When the response media type is `application/json`, clients may use a -`2xx` status code as an indication that the body contains a well-formed _GraphQL -response_. See [processing a response](#sec-Processing-a-response) for more -details. +Note: When the response media type is `application/json` and the status code is 4xx, +clients cannot count on the response being a well-formed _GraphQL response_. +See [processing a response](#sec-Processing-a-response) for more details. #### Examples From f73fd2c5a59714ff5a1b4247496b019e13b2f104 Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Sat, 27 Jul 2024 19:14:04 +0200 Subject: [PATCH 06/13] Mention intermediary server and 200 (and not 2xx) --- spec/GraphQLOverHTTP.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/spec/GraphQLOverHTTP.md b/spec/GraphQLOverHTTP.md index 62cb4643..4486a443 100644 --- a/spec/GraphQLOverHTTP.md +++ b/spec/GraphQLOverHTTP.md @@ -557,9 +557,10 @@ of `2xx` or `5xx` status codes when responding to invalid requests using the Note: URLs that enable GraphQL requests may enable other types of requests - see the [URL](#url) section. -Note: When the response media type is `application/json` and the status code is 4xx, -clients cannot count on the response being a well-formed _GraphQL response_. -See [processing a response](#sec-Processing-a-response) for more details. +Note: When a response media type is `application/json` and the status code is +not `200`, clients cannot count on the response being a well-formed _GraphQL +response_ because it might originate from an intermediary server. See +[processing a response](#sec-Processing-a-response) for more details. #### Examples @@ -744,8 +745,8 @@ proxy, or firewall, in certain environments. Those intermediary servers may not understand GraphQL: in the case of an error, they may return their own non-GraphQL `application/json` response with a -non-`2xx` status code. +non-`200` status code. -For this reason, if the response uses a non-`2xx` status code and the media type +For this reason, if the response uses a non-`200` status code and the media type of the response body is `application/json` then the client MUST NOT rely on the body to be a well-formed _GraphQL response_. From a337ac917b8a67ca54c69a968c727a3fdf1686ca Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Sat, 27 Jul 2024 19:21:57 +0200 Subject: [PATCH 07/13] spelling --- spec/GraphQLOverHTTP.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/GraphQLOverHTTP.md b/spec/GraphQLOverHTTP.md index 4486a443..30d74b4c 100644 --- a/spec/GraphQLOverHTTP.md +++ b/spec/GraphQLOverHTTP.md @@ -511,7 +511,7 @@ execution regardless of validation errors. ## Status Codes -The status codes depends on the media type with which the GraphQL response will +The status codes depend on the media type with which the GraphQL response will be served: ### application/json From 110d6adab7b832d3d2ba88fe72ac8279a636907e Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Sat, 27 Jul 2024 19:26:06 +0200 Subject: [PATCH 08/13] Backtrack, just add the link to the initial note --- spec/GraphQLOverHTTP.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/spec/GraphQLOverHTTP.md b/spec/GraphQLOverHTTP.md index 30d74b4c..1c0d3356 100644 --- a/spec/GraphQLOverHTTP.md +++ b/spec/GraphQLOverHTTP.md @@ -528,7 +528,8 @@ others) could originate from intermediary servers; since the client cannot determine if an `application/json` response with arbitrary status code is a well-formed _GraphQL response_ (because it cannot trust the source) the server must use `200` status code to guarantee to the client that the response has not -been generated or modified by an intermediary. +been generated or modified by an intermediary. See +[processing a response](#sec-Processing-a-response) for more details. If the _GraphQL response_ contains a non-null {data} entry then the server MUST use the `200` status code. @@ -557,11 +558,6 @@ of `2xx` or `5xx` status codes when responding to invalid requests using the Note: URLs that enable GraphQL requests may enable other types of requests - see the [URL](#url) section. -Note: When a response media type is `application/json` and the status code is -not `200`, clients cannot count on the response being a well-formed _GraphQL -response_ because it might originate from an intermediary server. See -[processing a response](#sec-Processing-a-response) for more details. - #### Examples The following examples provide guidance on how to deal with specific error cases From 22a648615a23a4c4937cfe6582f9e4088381838b Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Sat, 27 Jul 2024 22:48:50 +0200 Subject: [PATCH 09/13] Update spec/GraphQLOverHTTP.md Co-authored-by: Shane Krueger --- spec/GraphQLOverHTTP.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/spec/GraphQLOverHTTP.md b/spec/GraphQLOverHTTP.md index 1c0d3356..4ecdda3d 100644 --- a/spec/GraphQLOverHTTP.md +++ b/spec/GraphQLOverHTTP.md @@ -736,12 +736,9 @@ response; it still indicates successful execution. ## Processing a response -The source of a response may be an intermediary server, such as an API gateway, -proxy, or firewall, in certain environments. - -Those intermediary servers may not understand GraphQL: in the case of an error, -they may return their own non-GraphQL `application/json` response with a -non-`200` status code. +In certain environments, the source of a response may be an intermediary server, +such as an API gateway, proxy, or firewall. In the case of an error, they may return +their own non-GraphQL `application/json` response with a non-`200` status code. For this reason, if the response uses a non-`200` status code and the media type of the response body is `application/json` then the client MUST NOT rely on the From ddd4ba9ab9721b53b02faf49a08a8ac5f554e829 Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Sat, 27 Jul 2024 23:22:55 +0200 Subject: [PATCH 10/13] move processing a response to non-normative notes --- spec/GraphQLOverHTTP.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/spec/GraphQLOverHTTP.md b/spec/GraphQLOverHTTP.md index 4ecdda3d..1979d794 100644 --- a/spec/GraphQLOverHTTP.md +++ b/spec/GraphQLOverHTTP.md @@ -734,12 +734,17 @@ Note: The GraphQL specification and refers to the situation wherein a _GraphQL field error_ occurs as a partial response; it still indicates successful execution. +# Non-normative notes + ## Processing a response In certain environments, the source of a response may be an intermediary server, -such as an API gateway, proxy, or firewall. In the case of an error, they may return -their own non-GraphQL `application/json` response with a non-`200` status code. +such as an API gateway, proxy, or firewall. In the case of an error, they may +return their own non-GraphQL `application/json` response with a non-`200` status +code. + +For this reason, a client application can rely on the response being a +well-formed _GraphQL response_ if any of the following cases is true: -For this reason, if the response uses a non-`200` status code and the media type -of the response body is `application/json` then the client MUST NOT rely on the -body to be a well-formed _GraphQL response_. +- the response media type is `graphql-response+json` +- the response media type is `application/json` and the status code is `200` From 93e31ac1b45f9594c8db992f6bc434323799f28c Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Sat, 27 Jul 2024 23:27:02 +0200 Subject: [PATCH 11/13] forgot on application/ --- spec/GraphQLOverHTTP.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/GraphQLOverHTTP.md b/spec/GraphQLOverHTTP.md index 1979d794..64db1f1b 100644 --- a/spec/GraphQLOverHTTP.md +++ b/spec/GraphQLOverHTTP.md @@ -746,5 +746,5 @@ code. For this reason, a client application can rely on the response being a well-formed _GraphQL response_ if any of the following cases is true: -- the response media type is `graphql-response+json` +- the response media type is `application/graphql-response+json` - the response media type is `application/json` and the status code is `200` From bc439732c2435400c48338acfa5cffe54f1542be Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Thu, 29 Aug 2024 11:21:43 +0200 Subject: [PATCH 12/13] restore paragraph --- spec/GraphQLOverHTTP.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/spec/GraphQLOverHTTP.md b/spec/GraphQLOverHTTP.md index 64db1f1b..8d0dcab5 100644 --- a/spec/GraphQLOverHTTP.md +++ b/spec/GraphQLOverHTTP.md @@ -511,8 +511,19 @@ execution regardless of validation errors. ## Status Codes -The status codes depend on the media type with which the GraphQL response will -be served: +In case of errors that completely prevent the generation of a well-formed +_GraphQL response_, the server SHOULD respond with the appropriate status code +depending on the concrete error condition, and MUST NOT respond with a `2xx` +status code when using the `application/graphql-response+json` media type. + +Note: Typically the appropriate status code will be `400` (Bad Request). + +Note: This rule is "should" to maintain compatibility with legacy servers which +can return 200 status codes even when this type of error occurs, but only when +not using the `application/graphql-response+json` media type. + +Otherwise, the status codes depends on the media type with which the GraphQL +response will be served: ### application/json From 539dcd1599bcb7fcc75b66c851644af10ededcaa Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Tue, 25 Feb 2025 16:41:16 +0100 Subject: [PATCH 13/13] reintroduce the MUST NOT compliance requirement --- spec/GraphQLOverHTTP.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/GraphQLOverHTTP.md b/spec/GraphQLOverHTTP.md index 8d0dcab5..8524d274 100644 --- a/spec/GraphQLOverHTTP.md +++ b/spec/GraphQLOverHTTP.md @@ -534,6 +534,9 @@ The server SHOULD use the `200` status code for every response to a well-formed _GraphQL-over-HTTP request_, independent of any _GraphQL request error_ or _GraphQL field error_ raised. +If the response uses a non-`200` status code then the client MUST NOT rely on +the body to be a well-formed _GraphQL response_. + Note: A status code in the `4xx` or `5xx` ranges or status code `203` (and maybe others) could originate from intermediary servers; since the client cannot determine if an `application/json` response with arbitrary status code is a