@@ -136,7 +136,7 @@ schema with additional fields.
136136A _ server_ MAY forbid individual requests by a _ client_ to any endpoint for any
137137reason, for example to require authentication or payment; when doing so it
138138SHOULD use the relevant ` 4xx ` or ` 5xx ` status code. This decision SHOULD NOT be
139- based on the contents of a well formed GraphQL request .
139+ based on the contents of a well- formed _ GraphQL-over-HTTP request _ .
140140
141141Note: The _ server_ should not make authorization decisions based on any part of
142142the _ GraphQL request_ ; these decisions should be made by the _ GraphQL schema_
@@ -207,14 +207,18 @@ GET.
207207
208208## Request Parameters
209209
210- A _ GraphQL-over-HTTP request_ is formed of the following parameters:
210+ :: A _ GraphQL-over-HTTP request_ is an HTTP request that encodes the following
211+ parameters in one of the manners described in this specification:
211212
212- - {query} - A Document containing GraphQL Operations and Fragments to execute.
213- - {operationName} - (_ Optional_ ): The name of the Operation in the Document to
214- execute.
215- - {variables} - (_ Optional_ ): Values for any Variables defined by the Operation.
216- - {extensions} - (_ Optional_ ): This entry is reserved for implementors to extend
217- the protocol however they see fit.
213+ - {query} - (_ Required_ , string): The string representation of the Source Text
214+ of a GraphQL Document as specified in
215+ [ the Language section of the GraphQL specification] ( https://spec.graphql.org/draft/#sec-Language ) .
216+ - {operationName} - (_ Optional_ , string): The name of the Operation in the
217+ Document to execute.
218+ - {variables} - (_ Optional_ , map): Values for any Variables defined by the
219+ Operation.
220+ - {extensions} - (_ Optional_ , map): This entry is reserved for implementors to
221+ extend the protocol however they see fit.
218222
219223Note: When comparing _ GraphQL-over-HTTP request_ against the term
220224[ "request"] ( https://spec.graphql.org/draft/#request ) in the GraphQL
@@ -231,12 +235,15 @@ Note: Depending on the serialization format used, values of the aforementioned
231235parameters can be encoded differently but their names and semantics must stay
232236the same.
233237
234- Note: Specifying ` null ` in JSON (or equivalent values in other formats) as
235- values for optional request parameters is equivalent to not specifying them at
236- all.
238+ Note: An HTTP request that encodes parameters of the same names but of the wrong
239+ type, or that omits required parameters, is not a well-formed _ GraphQL-over-HTTP
240+ request_ .
241+
242+ Note: Specifying ` null ` for optional request parameters is equivalent to not
243+ specifying them at all.
237244
238- Note: Each of the {variables} and {extensions} parameters, if set, must have a
239- map as their value .
245+ Note: So long as it is a string, {query} does not have to parse or validate to
246+ be part of a well-formed _ GraphQL-over-HTTP request _ .
240247
241248## Accept
242249
@@ -269,25 +276,29 @@ still leveraging modern features if available in the server.
269276
270277## GET
271278
272- For HTTP GET requests, the GraphQL request parameters MUST be provided in the
273- query component of the request URL, encoded in the
279+ For HTTP GET requests, the _ GraphQL-over-HTTP request _ parameters MUST be
280+ provided in the query component of the request URL, encoded in the
274281` application/x-www-form-urlencoded ` format as specified by the
275282[ WhatWG URLSearchParams class] ( https://url.spec.whatwg.org/#interface-urlsearchparams ) .
276283
277- The ` query ` parameter MUST be the string representation of the Source Text of
278- the Document as specified in
284+ The { query} parameter MUST be the string representation of the source text of
285+ the document as specified in
279286[ the Language section of the GraphQL specification] ( https://spec.graphql.org/draft/#sec-Language ) .
280287
281- The ` operationName ` parameter, if present, must be a string.
288+ The { operationName} parameter, if present, must be a string.
282289
283- Each of the ` variables ` and ` extensions ` parameters, if used, MUST be
284- represented as a URL-encoded JSON string.
290+ Each of the { variables} and { extensions} parameters, if used, MUST be encoded as
291+ a JSON string.
285292
286- The ` operationName ` parameter, if supplied and not the empty string, represents
287- the name of the operation to be executed within the ` query ` .
293+ The { operationName} parameter, if supplied and not the empty string, represents
294+ the name of the operation to be executed within the { query} as a string .
288295
289- Setting the value of the ` operationName ` parameter to the empty string is
290- equivalent to omitting the ` operationName ` parameter.
296+ Note: In the final URL all of these parameters will appear in the query
297+ component of the request URL as URL-encoded values due to the WhatWG
298+ URLSearchParams encoding specified above.
299+
300+ Setting the value of the {operationName} parameter to the empty string is
301+ equivalent to omitting the {operationName} parameter.
291302
292303Note: By the above, ` operationName=null ` represents an operation with the name
293304` "null" ` (such as ` query null { __typename } ` ). If a literal ` null ` is desired,
@@ -323,8 +334,8 @@ long-established semantics of safe methods within HTTP.
323334
324335A GraphQL POST request instructs the server to perform a query or mutation
325336operation. A GraphQL POST request MUST have a body which contains values of the
326- request parameters encoded in one of the officially recognized GraphQL media
327- types, or another media type supported by the server.
337+ _ GraphQL-over-HTTP request _ parameters encoded in one of the officially
338+ recognized GraphQL media types, or another media type supported by the server.
328339
329340A client MUST indicate the media type of a request body using the ` Content-Type `
330341header as specified in [ RFC7231] ( https://datatracker.ietf.org/doc/html/rfc7231 ) .
@@ -354,8 +365,8 @@ compliant _server_.
354365
355366### JSON Encoding
356367
357- When encoded in JSON, a GraphQL -over-HTTP request is a JSON object (map), with
358- the properties specified by the GraphQL-over-HTTP request:
368+ When encoded in JSON, a _ GraphQL -over-HTTP request _ is encoded as a JSON object
369+ (map), with the properties specified by the GraphQL-over-HTTP request:
359370
360371- {query} - the string representation of the Source Text of the Document as
361372 specified in
@@ -437,10 +448,10 @@ in the `Accept` HTTP header, the server MUST either:
4374482 . Respond with a ` 406 Not Acceptable ` status code and stop processing the
438449 request.
439450
440- A server MUST support requests which accept the ` application/json ` media type
441- (as indicated by the ` Accept ` header).
451+ A server MUST support any _ GraphQL-over-HTTP request _ which accepts the
452+ ` application/json ` media type (as indicated by the ` Accept ` header).
442453
443- A server SHOULD support requests which accept the
454+ A server SHOULD support any _ GraphQL-over-HTTP request _ which accepts the
444455` application/graphql-response+json ` media type (as indicated by the ` Accept `
445456header).
446457
@@ -455,42 +466,54 @@ January 2025.
455466
456467### Legacy watershed
457468
458- From 1st January 2025 (` 2025-01-01T00:00:00Z ` ), a server MUST support requests
459- which accept the ` application/graphql-response+json ` media type (as indicated by
460- the ` Accept ` header) using the UTF-8 encoding.
469+ From 1st January 2025 (` 2025-01-01T00:00:00Z ` ), a server MUST support any
470+ _ GraphQL-over-HTTP request_ which accepts the
471+ ` application/graphql-response+json ` media type (as indicated by the ` Accept `
472+ header) using the UTF-8 encoding.
461473
462474Before 1st January 2025 (` 2025-01-01T00:00:00Z ` ), if the client does not supply
463- an ` Accept ` header, the server SHOULD treat the request as if it had
464- ` Accept: application/json ` . From 1st January 2025 (` 2025-01-01T00:00:00Z ` ), if
465- the client does not supply an ` Accept ` header, the server SHOULD treat the
466- request as if it had ` Accept: application/graphql-response+json ` .
475+ an ` Accept ` header, the server SHOULD treat the _ GraphQL-over-HTTP request_ as
476+ if it had ` Accept: application/json ` . From 1st January 2025
477+ (` 2025-01-01T00:00:00Z ` ), if the client does not supply an ` Accept ` header, the
478+ server SHOULD treat the _ GraphQL-over-HTTP request_ as if it had
479+ ` Accept: application/graphql-response+json ` .
467480
468481Note: This default is in place to maintain compatibility with legacy clients.
469482
470483## Validation
471484
472- Validation of a well-formed GraphQL -over-HTTP request SHOULD apply all the
485+ Validation of a well-formed _ GraphQL -over-HTTP request _ SHOULD apply all the
473486[ validation rules] ( https://spec.graphql.org/draft/#sec-Validation ) specified by
474487the GraphQL specification.
475488
476489The server MAY, at its discretion, apply additional validation rules.
477490
491+ Note: Examples of additional validation rules the server may apply include depth
492+ limit, complexity limit, etc.
493+
478494## Execution
479495
480- Execution of a GraphQL -over-HTTP request follows
496+ Execution of a _ GraphQL -over-HTTP request _ follows
481497[ GraphQL's ExecuteRequest()] ( < https://spec.graphql.org/draft/#ExecuteRequest() > )
482498algorithm.
483499
500+ Note: In general, a _ GraphQL-over-HTTP request_ that does not pass validation
501+ should not be executed; however in certain circumstances, for example persisted
502+ operations that were previously known to be valid, the server may attempt
503+ execution regardless of validation errors.
504+
484505## Status Codes
485506
486507In case of errors that completely prevent the generation of a well-formed
487508_ GraphQL response_ , the server SHOULD respond with the appropriate status code
488- depending on the concrete error condition.
509+ depending on the concrete error condition, and MUST NOT respond with a ` 2xx `
510+ status code when using the ` application/graphql-response+json ` media type.
489511
490- Note: Typically this will be the ` 400 ` (Bad Request) status code .
512+ Note: Typically the appropriate status code will be ` 400 ` (Bad Request).
491513
492514Note: This rule is "should" to maintain compatibility with legacy servers which
493- can return 200 status codes even when this type of error occurs.
515+ can return 200 status codes even when this type of error occurs, but only when
516+ not using the ` application/graphql-response+json ` media type.
494517
495518Otherwise, the status codes depends on the media type with which the GraphQL
496519response will be served:
@@ -500,8 +523,9 @@ response will be served:
500523This section only applies when the response body is to use the
501524` application/json ` media type.
502525
503- The server SHOULD use the ` 200 ` status code, independent of any _ GraphQL request
504- error_ or _ GraphQL field error_ raised.
526+ The server SHOULD use the ` 200 ` status code for every response to a well-formed
527+ _ GraphQL-over-HTTP request_ , independent of any _ GraphQL request error_ or
528+ _ GraphQL field error_ raised.
505529
506530Note: A status code in the ` 4xx ` or ` 5xx ` ranges or status code ` 203 ` (and maybe
507531others) could originate from intermediary servers; since the client cannot
@@ -517,13 +541,86 @@ Note: This indicates that no _GraphQL request error_ was raised, though one or
517541more _ GraphQL field error_ may have been raised this is still a successful
518542execution - see "partial response" in the GraphQL specification.
519543
520- The server SHOULD NOT use a ` 4xx ` or ` 5xx ` status code.
544+ The server SHOULD NOT use a ` 4xx ` or ` 5xx ` status code for a response to a
545+ well-formed _ GraphQL-over-HTTP request_ .
546+
547+ Note: For compatibility with legacy servers, this specification allows the use
548+ of ` 4xx ` or ` 5xx ` status codes for a failed well-formed _ GraphQL-over-HTTP
549+ request_ where the response uses the ` application/json ` media type, but it is
550+ strongly discouraged. To use ` 4xx ` and ` 5xx ` status codes in these situations,
551+ please use the ` application/graphql-response+json ` media type.
552+
553+ If the URL is not used for other purposes, the server SHOULD use a ` 4xx ` status
554+ code to respond to a request that is not a well-formed _ GraphQL-over-HTTP
555+ request_ .
521556
522557Note: For compatibility with legacy servers, this specification allows the use
523- of ` 4xx ` or ` 5xx ` status codes for failed requests where the response uses the
524- ` application/json ` media type, but it is strongly discouraged. To use ` 4xx ` and
525- ` 5xx ` status codes, please use the ` application/graphql-response+json ` media
526- type.
558+ of ` 2xx ` or ` 5xx ` status codes when responding to invalid requests using the
559+ ` application/json ` media type, but it is strongly discouraged.
560+
561+ Note: URLs that enable GraphQL requests may enable other types of requests - see
562+ the [ URL] ( #url ) section.
563+
564+ #### Examples
565+
566+ The following examples provide guidance on how to deal with specific error cases
567+ when using the ` application/json ` media type to encode the response body:
568+
569+ ##### JSON parsing failure
570+
571+ For example a POST request body of ` NONSENSE ` or ` {"query": ` (note: invalid
572+ JSON).
573+
574+ Requests that the server cannot interpret SHOULD result in status code ` 400 `
575+ (Bad Request).
576+
577+ ##### Invalid parameters
578+
579+ For example a POST request body of ` {"qeury": "{__typename}"} ` (note: typo) or
580+ ` {"query": "query Q ($i:Int!) { q(i: $i) }", "variables": [7]} ` (note: invalid
581+ shape for ` variables ` ).
582+
583+ A request that does not constitute a well-formed _ GraphQL-over-HTTP request_
584+ SHOULD result in status code ` 400 ` (Bad Request).
585+
586+ ##### Document parsing failure
587+
588+ For example a POST request body of ` {"query": "{"} ` .
589+
590+ Requests where the _ GraphQL document_ cannot be parsed SHOULD result in status
591+ code ` 200 ` (Okay).
592+
593+ ##### Document validation failure
594+
595+ Requests that fail to pass _ GraphQL validation_ , the server SHOULD NOT execute
596+ the request and SHOULD return a status code of ` 200 ` (Okay).
597+
598+ ##### Operation cannot be determined
599+
600+ If [ GetOperation()] ( < https://spec.graphql.org/draft/#GetOperation() > ) raises a
601+ _ GraphQL request error_ , the server SHOULD NOT execute the request and SHOULD
602+ return a status code of ` 200 ` (Okay).
603+
604+ ##### Variable coercion failure
605+
606+ If
607+ [ CoerceVariableValues()] ( < https://spec.graphql.org/draft/#CoerceVariableValues() > )
608+ raises a _ GraphQL request error_ , the server SHOULD NOT execute the request and
609+ SHOULD return a status code of ` 200 ` (Okay).
610+
611+ ##### Field errors encountered during execution
612+
613+ If the operation is executed and no _ GraphQL request error_ is raised then the
614+ server SHOULD respond with a status code of ` 200 ` (Okay). This is the case even
615+ if a _ GraphQL field error_ is raised during
616+ [ GraphQL's ExecuteQuery()] ( < https://spec.graphql.org/draft/#ExecuteQuery() > ) or
617+ [ GraphQL's ExecuteMutation()] ( < https://spec.graphql.org/draft/#ExecuteMutation() > ) .
618+
619+ <!--
620+ When we add support for subscriptions,
621+ [GraphQL's MapSourceToResponseEvent()](<https://spec.graphql.org/draft/#MapSourceToResponseEvent()>)
622+ should be added to the above.
623+ -->
527624
528625### application/graphql-response+json
529626
@@ -561,8 +658,8 @@ Note: The GraphQL specification indicates that the only situation in which the
561658_ GraphQL response_ does not include the {data} entry is one in which the
562659{errors} entry is populated.
563660
564- If the GraphQL request is invalid (e.g. it is malformed , or does not pass
565- validation) then the server SHOULD reply with ` 400 ` status code.
661+ If the request is not a well-formed _ GraphQL-over-HTTP request _ , or it does not
662+ pass validation, then the server SHOULD reply with ` 400 ` status code.
566663
567664If the client is not permitted to issue the GraphQL request then the server
568665SHOULD reply with ` 403 ` , ` 401 ` or similar appropriate status code.
@@ -587,8 +684,8 @@ For example a POST request body of `{"qeury": "{__typename}"}` (note: typo) or
587684` {"query": "query Q ($i:Int!) { q(i: $i) }", "variables": [7]} ` (note: invalid
588685shape for ` variables ` ).
589686
590- Requests that do not constitute a well-formed _ GraphQL-over-HTTP request_ should
591- result in status code ` 400 ` (Bad Request).
687+ A request that does not constitute a well-formed _ GraphQL-over-HTTP request_
688+ SHOULD result in status code ` 400 ` (Bad Request).
592689
593690##### Document parsing failure
594691
@@ -602,15 +699,6 @@ code `400` (Bad Request).
602699Requests that fail to pass _ GraphQL validation_ SHOULD be denied execution with
603700a status code of ` 400 ` (Bad Request).
604701
605- Note: In certain circumstances, for example persisted operations that were
606- previously known to be valid, the server MAY attempt execution regardless of
607- validation errors.
608-
609- Note: Validation rules include those specified in
610- [ the Validation section of the GraphQL specification] ( http://spec.graphql.org/draft/#sec-Validation ) ,
611- and any custom validation rules the server is using (for example: depth limit,
612- complexity limit).
613-
614702##### Operation cannot be determined
615703
616704If [ GetOperation()] ( < https://spec.graphql.org/draft/#GetOperation() > ) raises a
0 commit comments