Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 53 additions & 47 deletions spec/GraphQLOverHTTP.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ Server URLs which enable GraphQL requests MAY also be used for other purposes,
as long as they don't conflict with the server's responsibility to handle
GraphQL requests.

It is RECOMMENDED to end the path component of the URL with `/graphql`, for
example:
It is a common convention to end the path component of the URL with `/graphql`,
for example:
Comment on lines +137 to +138

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of graphql security hardening guides argue against using /graphql. My take is that if you're relying on the fact that your endpoint is non-standard for security then you're at a bad place.

Still, I don't really see the benefit of recommending the path component. While it's all about discoverability for developers/tooling, it isn't something we can rely on. Saying that this is a common convention is better than recommending that implementers follow the convention. Good change.


```url example
http://example.com/graphql
Expand Down Expand Up @@ -225,8 +225,8 @@ be part of a well-formed _GraphQL-over-HTTP request_.
## Accept

A client MUST indicate the media types that it supports in responses using the
`Accept` HTTP header as specified in
[RFC7231](https://datatracker.ietf.org/doc/html/rfc7231).
`Accept` HTTP header; this header is specified in
[IETF RFC 9110](https://httpwg.org/specs/rfc9110.html#field.accept).

Note: If a client does not supply the `Accept` header then the server may
respond with an error, or with any content type it chooses (including serving a
Expand All @@ -241,7 +241,7 @@ the `Accept` header.
this specification.

If it is not known that the server supports `application/graphql-response+json`,
it is RECOMMENDED that the client set the `Accept` header to
the client SHOULD set the `Accept` header to
`application/graphql-response+json, application/json;q=0.9`.
Comment on lines 243 to 245

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why shouldn't the client set the Accept header to application/graphql-response+json, application/json;q=0.9 if it is known that the server supports application/graphql-response+json? 😸

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it knows the server supports the desired media type, why Accept a worse one when you know it should never be used?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My point is that the client shouldn’t really care. The result will be the same. The server will honor the preferred media type and the client can just use the recommended accept header.


## GET
Expand Down Expand Up @@ -277,12 +277,12 @@ either omit {operationName} or set it to the empty string.
GET requests MUST NOT be used for executing mutation operations. If the values
of {query} and {operationName} indicate that a mutation operation is to be
executed, the server MUST respond with an appropriate `4xx` status code and halt
execution. Using `405` (Method Not Allowed) is RECOMMENDED. This restriction is
necessary to conform with the long-established semantics of safe methods within
HTTP.
execution; status code `405` (Method Not Allowed) is RECOMMENDED. This

@benjie benjie Aug 3, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've left this RECOMMENDED in place, it's the only one, but writing the sentence to use both MUST and SHOULD read really awkwardly and I believe RFC2119 gives us a choice of words to allow us to avoid these kinds of linguistic shenanigans.

restriction is necessary to conform with the long-established semantics of safe
methods within HTTP.

Note: If status code `405` is used then the `Allow` header must be included as
per [RFC9110](https://httpwg.org/specs/rfc9110.html#status.405).
required by [IETF RFC 9110](https://httpwg.org/specs/rfc9110.html#status.405).

### Example

Expand Down Expand Up @@ -312,7 +312,8 @@ _GraphQL-over-HTTP request_ parameters encoded in one of the officially
recognized GraphQL media types, or another media type supported by the server.

A client MUST indicate the media type of a request body using the `Content-Type`
header as specified in [RFC7231](https://datatracker.ietf.org/doc/html/rfc7231).
header; this header is specified in
[IETF RFC 9110](https://httpwg.org/specs/rfc9110.html#field.content-type).

A server MUST support POST requests encoded with the `application/json` media
type (as indicated by the `Content-Type` header) encoded with UTF-8.
Expand Down Expand Up @@ -353,9 +354,8 @@ When encoded in JSON, a _GraphQL-over-HTTP request_ is encoded as a JSON object
[the Response section of the GraphQL specification](https://spec.graphql.org/draft/#sec-Response-Format.Response).

All other property names are reserved for future expansion. If implementers need
to add additional information to a request they MUST do so via other means; the
RECOMMENDED approach is to add an implementer-scoped entry to the {extensions}
object.
to add additional information to a request they MUST do so via other means, for
example by adding an implementer-scoped entry to the {extensions} object.
Comment on lines -357 to +358

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding to extensions is the "recommended" approach; but if you choose to set it via headers I wouldn't say you "should not" have done that. So I've lowered this to an example.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This read better with RECOMMENDED.

A possible direction might be to point out that this is one of the reasons the extensions object exists and link to the spec for more informations. That would be more informative to users new to the spec.


Servers receiving a request with additional properties MUST ignore properties
they do not understand.
Expand Down Expand Up @@ -410,7 +410,7 @@ validating and executing the requested operation if successful, and describes
any errors encountered during the request.

A server must comply with
[RFC7231](https://datatracker.ietf.org/doc/html/rfc7231).
[IETF RFC 9110](https://httpwg.org/specs/rfc9110.html).

## Body

Expand All @@ -433,9 +433,9 @@ header and attempt to encode the response in the highest priority media type
listed that is supported by the server.

In alignment with the
[HTTP 1.1 Accept](https://tools.ietf.org/html/rfc7231#section-5.3.2)
specification, when a client does not include at least one supported media type
in the `Accept` HTTP header, the server MUST either:
[IETF RFC 9110 Content Negotiation](https://httpwg.org/specs/rfc9110.html#content.negotiation),
when the request includes an `Accept` header and no supported media type is
acceptable according to that header, the server MUST either:

1. Respond with a `406 Not Acceptable` status code and stop processing the
request; OR
Expand All @@ -444,8 +444,8 @@ in the `Accept` HTTP header, the server MUST either:

If the `Accept` header does not indicate support for one of the server's
preferred media types but does indicate support for `application/json`, as may
be the case for a _legacy client_, it is RECOMMENDED to perform the request
following the requirements of this specification as if the request had specified
be the case for a _legacy client_, the request SHOULD be performed following the
requirements of this specification as if the request had specified
`Accept: application/graphql-response+json`, except any response that produces a
`2xx` status code should replace the `Content-Type` header with
`Content-Type: application/json`.
Expand All @@ -459,8 +459,8 @@ is successful (HTTP `2xx`) or when it explicitly declares it is a GraphQL
response (`Content-Type: application/graphql-response+json`).

If the `Accept` header is present but does not indicate support for any of the
server's supported media types or `application/json`, it is RECOMMENDED to
respond with `406 Not Acceptable`.
server's supported media types or `application/json`, the server SHOULD respond
with `406 Not Acceptable`.

Note: It is unlikely that a client can process a response that does not match
one of the media types it has requested, hence `406 Not Acceptable` being the
Expand Down Expand Up @@ -535,47 +535,52 @@ reply with an appropriate `4xx` or `5xx` status code:

- If the failure is due to an issue in the request itself, the appropriate `4xx`
status code should be used:
- If a mutation is attempted via the `GET` verb, status code `405` is
RECOMMENDED.
- If an unsupported HTTP method is used, status code `405` is RECOMMENDED.
- If the `Content-Type` of the request is not supported, status code `415` is
RECOMMENDED.
- If a mutation is attempted via the `GET` verb, status code `405` SHOULD be
used.
- If the request uses an unsupported HTTP method, status code `405` SHOULD be
used.
- If the `Content-Type` of the request is not supported, status code `415`
SHOULD be used.
- If none of the media types in the `Accept` header are supported and the
`Accept` header does not include `application/json`, then status code `406`
is RECOMMENDED.
SHOULD be used.
- If the client did not produce a request within the time that the server was
prepared to wait, status code `408` is RECOMMENDED.
- If the size of the URI was too large, status code `414` is RECOMMENDED (and
prepared to wait, status code `408` SHOULD be used.
- If the size of the URI was too large, status code `414` SHOULD be used (and
the client should consider using `POST` instead).
- If the size of the request headers (or any one header) was too large, status
code `431` is RECOMMENDED.
- If the size of the `POST` request body was too large, status code `413` is
RECOMMENDED.
- If the JSON body of the request could not be parsed, status code `400` is
RECOMMENDED.
code `431` SHOULD be used.
- If the size of the `POST` request body was too large, status code `413`
SHOULD be used.
- If the JSON body of the request could not be parsed, status code `400`
SHOULD be used.
- If the request is not a well-formed _GraphQL-over-HTTP request_, status code
`422` is RECOMMENDED.
`422` SHOULD be used.
- If the GraphQL document in the request cannot be parsed, status code `400`
is RECOMMENDED.
- If the request does not pass GraphQL validation, status code `422` is
RECOMMENDED.
SHOULD be used.
- If the request does not pass GraphQL validation, status code `422` SHOULD be
used.
- If the operation to execute cannot be unambiguously determined, status code
`422` is RECOMMENDED.
`422` SHOULD be used.
- If the variable values cannot be coerced to match the operation's variable
definitions, status code `422` is RECOMMENDED.
definitions, status code `422` SHOULD be used.
- If the client is not permitted to issue the GraphQL request, then the server
SHOULD reply with `401`, `403` or similar appropriate status code.
- If the server cannot process the request due to being a short and stout
ceramic vessel, status code `418` is RECOMMENDED.
ceramic vessel, status code `418` SHOULD be used.
- When the server is the reason for failure, the appropriate `5xx` status code
should be used. For example, if the server is not able to execute requests at
this time due to maintenance or load-shedding, then status code `503` is
RECOMMENDED.
this time due to maintenance or load-shedding, then status code `503` SHOULD
be used.

Note: The GraphQL specification indicates that the only situation in which the
_GraphQL response_ does not include the {data} entry is one in which the
{errors} entry is populated.

Note: Implementers should be careful to always comply with the HTTP spec, for
example when using status code `405` the `Allow` header MUST be specified, as
required by [RFC9110](https://httpwg.org/specs/rfc9110.html#status.405).

### Examples

The following examples provide guidance on how to deal with specific error
Expand Down Expand Up @@ -645,7 +650,8 @@ response; it still indicates successful execution.
# Non-normative notes

This section of the specification is non-normative, even where the words and
phrases specified in RFC2119 are used.
phrases specified in [IETF RFC 2119](https://tools.ietf.org/html/rfc2119) are
used.

## Partial success

Expand Down Expand Up @@ -736,9 +742,9 @@ HTTP request size would suggest.
### Other resources

For more detailed security considerations, please refer to
[RFC 7231](https://tools.ietf.org/html/rfc7231),
[RFC 6454](https://tools.ietf.org/html/rfc6454), other relevant RFCs, and other
resources such as [OWASP](https://owasp.org).
[IETF RFC 9110](https://httpwg.org/specs/rfc9110.html),
[IETF RFC 6454](https://tools.ietf.org/html/rfc6454), other relevant RFCs, and
other resources such as [OWASP](https://owasp.org).

## Future compatibility

Expand Down
Loading