11# A. Appendix: ` application/json ` responses
22
3+ This section only applies when the response body uses or may use the legacy
4+ ` application/json ` media type for compatibility reasons.
5+
36Previous to this specification, the article
47[ Serving over HTTP] ( https://graphql.org/learn/serving-over-http )
58([ WayBack Machine entry, 1st June 2022] ( https://web.archive.org/web/20220601155421/https://graphql.org/learn/serving-over-http ) )
6- on the graphql.org website served as guidance.
7-
8- This article used ` application/json ` as media type for the response.
9+ on the graphql.org website served as guidance. This article used
10+ ` application/json ` as media type for the response.
911
1012In some cases, the response received by a client may not originate from a
1113GraphQL service, but instead from an intermediary—such as an API gateway, proxy,
@@ -15,41 +17,43 @@ response with `4xx` or `5xx` status code and potentially using the standard
1517` application/json ` media type to encode the reason for the error. Such a
1618response is unlikely to be a valid GraphQL response.
1719
18- For this reason, a client application receiving an ` application/json ` response,
19- could rely on the response being a well-formed _ GraphQL response_ only if the
20- status code is ` 200 ` .
21-
22- This caused multiple observability issues because it was challenging to
23- distinguish a well-formed _ GraphQL response_ from an intermediary response.
24-
25- ` application/graphql-response+json ` allows to distinguish a well-formed _ GraphQL
26- response_ from another intermediary response and is the required media type
27- moving forward.
28-
29- For compatibility reasons, clients and servers may support ` application/json ` as
30- described in this section.
31-
32- Note: Servers may wish to only support the ` application/graphql-response+json `
33- media type so that related HTTP tooling may utilize the HTTP status codes of
34- responses without having to be GraphQL-aware.
35-
36- ### Accept
37-
38- To maximize compatibility, a client may include the media type
39- ` application/json ` in the ` Accept ` header. When doing this, it is recommended
40- that the client set the ` Accept ` header to
20+ For this reason, a client receiving an ` application/json ` response can only rely
21+ on the response being a well-formed _ GraphQL response_ if the status code is
22+ ` 200 ` . However, responding to all GraphQL requests with HTTP 200 means that
23+ intermediary observability software cannot determine the status of the request
24+ without processing the response body.
25+
26+ Responding with the ` application/graphql-response+json ` media type enables the
27+ client to distinguish a well-formed _ GraphQL response_ from an intermediary
28+ response, and is required by both clients and servers under this specification.
29+ This appendix exists to increase interoperability with legacy clients/servers
30+ that have not yet adopted this specification.
31+
32+ Note: Servers may wish to respond to ` Accept: application/json ` requests with
33+ the ` application/graphql-response+json ` media type so that related HTTP tooling
34+ may utilize the HTTP status codes of responses without having to be
35+ GraphQL-aware. Doing so may impact error-handling behavior of legacy clients,
36+ and may prevent legacy clients from processing responses if they require the
37+ response ` Content-Type ` to be ` application/json ` .
38+
39+ ## Accept
40+
41+ To enable compatibility with legacy servers, the client SHOULD include the media
42+ type ` application/json ` in the ` Accept ` header and it is RECOMMENDED that such a
43+ client set the ` Accept ` header to
4144` application/graphql-response+json, application/json;q=0.9 ` .
4245
4346Note: The ` q=0.9 ` parameter tells content negotiation that ` application/json `
4447should only be used if ` application/graphql-response+json ` is not supported.
4548
46- ### Status codes
49+ ## Status codes
4750
48- When using the ` application/json ` media type, the server should use the ` 200 `
49- status code for every response to a well-formed _ GraphQL-over-HTTP request_ ,
50- independent of any _ GraphQL request error_ or _ GraphQL field error_ raised.
51+ When responding with the legacy ` application/json ` media type, the server SHOULD
52+ use the ` 200 ` status code for every response to a well-formed _ GraphQL-over-HTTP
53+ request_ independent of any _ GraphQL request error_ or _ GraphQL field error_
54+ raised.
5155
52- If the response uses a non-` 200 ` status code then the client must not rely on
56+ If the response uses a non-` 2xx ` status code then the client MUST NOT rely on
5357the body to be a well-formed _ GraphQL response_ .
5458
5559Note: A status code in the ` 4xx ` or ` 5xx ` ranges or status code ` 203 ` (and maybe
@@ -60,14 +64,14 @@ _GraphQL response_ (because it cannot trust the source) the server must use
6064generated or modified by an intermediary. See
6165[ processing a response] ( #sec-Processing-a-response ) for more details.
6266
63- If the _ GraphQL response_ contains a non-null {data} entry then the server must
67+ If the _ GraphQL response_ contains a non-null {data} entry then the server MUST
6468use the ` 200 ` status code.
6569
6670Note: This indicates that no _ GraphQL request error_ was raised, though one or
6771more _ GraphQL field error_ may have been raised this is still a successful
6872execution - see "partial response" in the GraphQL specification.
6973
70- The server should not use a ` 4xx ` or ` 5xx ` status code for a response to a
74+ The server SHOULD NOT use a ` 4xx ` or ` 5xx ` status code for a response to a
7175well-formed _ GraphQL-over-HTTP request_ .
7276
7377Note: For compatibility with legacy servers, this specification allows the use
@@ -76,7 +80,7 @@ request_ where the response uses the `application/json` media type, but it is
7680strongly discouraged. To use ` 4xx ` and ` 5xx ` status codes in these situations,
7781please use the ` application/graphql-response+json ` media type.
7882
79- If the URL is not used for other purposes, the server should use a ` 4xx ` status
83+ If the URL is not used for other purposes, the server SHOULD use a ` 4xx ` status
8084code to respond to a request that is not a well-formed _ GraphQL-over-HTTP
8185request_ .
8286
@@ -87,20 +91,20 @@ of `2xx` or `5xx` status codes when responding to invalid requests using the
8791Note: URLs that enable GraphQL requests may enable other types of requests - see
8892the [ URL] ( #url ) section.
8993
90- #### Examples
94+ ### Examples
9195
9296The following examples provide guidance on how to deal with specific error cases
9397when using the ` application/json ` media type to encode the response body:
9498
95- ##### JSON parsing failure
99+ #### JSON parsing failure
96100
97101For example a POST request body of ` NONSENSE ` or ` {"query": ` (note: invalid
98102JSON).
99103
100104Requests that the server cannot interpret SHOULD result in status code ` 400 `
101105(Bad Request).
102106
103- ##### Invalid parameters
107+ #### Invalid parameters
104108
105109For example a POST request body of ` {"qeury": "{__typename}"} ` (note: typo) or
106110` {"query": "query Q ($i:Int!) { q(i: $i) }", "variables": [7]} ` (note: invalid
@@ -109,25 +113,25 @@ shape for `variables`).
109113A request that does not constitute a well-formed _ GraphQL-over-HTTP request_
110114SHOULD result in status code ` 400 ` (Bad Request).
111115
112- ##### Document parsing failure
116+ #### Document parsing failure
113117
114118For example a POST request body of ` {"query": "{"} ` .
115119
116120Requests where the _ GraphQL document_ cannot be parsed SHOULD result in status
117121code ` 200 ` (Okay).
118122
119- ##### Document validation failure
123+ #### Document validation failure
120124
121125If a request fails to pass _ GraphQL validation_ , the server SHOULD NOT execute
122126the request and SHOULD return a status code of ` 200 ` (Okay).
123127
124- ##### Operation cannot be determined
128+ #### Operation cannot be determined
125129
126130If [ GetOperation()] ( < https://spec.graphql.org/draft/#GetOperation() > ) raises a
127131_ GraphQL request error_ , the server SHOULD NOT execute the request and SHOULD
128132return a status code of ` 200 ` (Okay).
129133
130- ##### Variable coercion failure
134+ #### Variable coercion failure
131135
132136If
133137[ CoerceVariableValues()] ( < https://spec.graphql.org/draft/#CoerceVariableValues() > )
@@ -146,7 +150,7 @@ For example the well-formed GraphQL-over-HTTP request:
146150would fail variable coercion as the value for ` id ` would fail to satisfy the
147151query document's expectation that ` id ` is non-null.
148152
149- ##### Field errors encountered during execution
153+ #### Field errors encountered during execution
150154
151155If the operation is executed and no _ GraphQL request error_ is raised then the
152156server SHOULD respond with a status code of ` 200 ` (Okay). This is the case even
0 commit comments