Skip to content
Open
1 change: 1 addition & 0 deletions cspell.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ words:
# Terms of art
- roadmap
- endianness
- cacheable
- interoperation
- monospace
- openwebfoundation
Expand Down
90 changes: 84 additions & 6 deletions spec/GraphQLOverHTTP.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,9 @@ assumed).

# Request

A server MUST support _GraphQL-over-HTTP request_ via `POST`, and MAY support
_GraphQL-over-HTTP request_ via other HTTP methods, such as `GET`.
A server MUST support _GraphQL-over-HTTP request_ via `POST`, SHOULD support
_GraphQL-over-HTTP request_ via `QUERY`, and MAY support _GraphQL-over-HTTP
request_ via other HTTP methods, such as `GET`.

## GraphQL-over-HTTP Request

Expand Down Expand Up @@ -307,9 +308,14 @@ http://example.com/graphql?query=query(%24id%3A%20ID!)%7Buser(id%3A%24id)%7Bname
## POST

A POST request instructs the GraphQL-over-HTTP server to perform a query or
mutation operation. The request MUST have a body which contains values of the
_GraphQL-over-HTTP request_ parameters encoded in one of the officially
recognized GraphQL media types, or another media type supported by the server.
mutation operation.

Note: when possible, it is recommended to perform query operations using
idempotent and cacheable QUERY requests instead of POST requests.

The request MUST have a body which contains values of the _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; this header is specified in
Expand Down Expand Up @@ -403,6 +409,76 @@ And the body:
}
```

## QUERY

A [QUERY](https://httpwg.org/specs/rfc10008.html) request instructs the
GraphQL-over-HTTP server to perform a query operation. The request MUST have a
body which contains values of the _GraphQL-over-HTTP request_ parameters encoded
in one of the officially recognized GraphQL media types, or another media type
supported by the server.

As stated in [IETF RFC 10008](https://httpwg.org/specs/rfc10008.html#query) a
client MUST indicate the media type of a request body using the `Content-Type`
header; this header is specified in
[IETF RFC 9110](https://httpwg.org/specs/rfc9110.html#field.accept).

If a server supports QUERY requests, it MUST support QUERY requests using the
`application/json` media type (as indicated by the `Content-Type` header)
encoded with UTF-8.

A server SHOULD indicate it supports QUERY using the HTTP semantics, as
indicated in the
[IETF RFC 10008](https://httpwg.org/specs/rfc10008.html#example.discovery.method).

For QUERY requests using an officially recognized GraphQL `Content-Type` without
indicating an encoding, the server MUST assume the encoding is `utf-8`.

If the client does not supply a `Content-Type` header with a QUERY request, the
server SHOULD reject the request using the appropriate `4xx` status code.

Note: Rejecting such requests encourages clients to supply a `Content-Type`
header with every QUERY request. A server has the option to assume any media
type they wish when none is supplied, with the understanding that parsing the
request may fail.

A server MAY support QUERY requests encoded with and/or accepting other media
types or encodings.

If a client does not know the media types the server supports then it SHOULD
encode the request body in JSON (i.e. with `Content-Type: application/json`).

QUERY 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 error status code `422` (Unprocessable
Entity) and halt execution. This restriction is necessary to conform with the
long-established semantics of safe methods within HTTP.

### JSON Encoding

When encoded in JSON, a _GraphQL-over-HTTP request_ is encoded as a JSON object
(map), with the properties specified by the GraphQL-over-HTTP request:

- {query} - the string representation of the Source Text of the Document as
specified in
[the Language section of the GraphQL specification](https://spec.graphql.org/draft/#sec-Language).
- {operationName} - an optional string
- {variables} - an optional object (map), the keys of which are the variable
names and the values of which are the variable values
- {extensions} - an optional object (map) reserved for implementers to extend
the protocol however they see fit, as specified in
[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.

Servers receiving a request with additional properties MUST ignore properties
they do not understand.

Specifying `null` for optional request parameters is equivalent to not
specifying them at all.

# Response

When a server receives a well-formed _GraphQL-over-HTTP request_, it must return
Expand Down Expand Up @@ -552,6 +628,8 @@ _GraphQL request error result_ and the server MUST reply with an appropriate
status code should be used:
- If a mutation is attempted via the `GET` verb, status code `405` SHOULD be
used.
- If a mutation is attempted via the `QUERY` verb, status code `422` 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`
Expand All @@ -562,7 +640,7 @@ _GraphQL request error result_ and the server MUST reply with an appropriate
- If the client did not produce a request within the time that the server was
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).
the client should consider using `POST` or `QUERY` instead).
- If the size of the request headers (or any one header) was too large, status
code `431` SHOULD be used.
- If the size of the `POST` request body was too large, status code `413`
Expand Down
Loading