Skip to content
Closed
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
75 changes: 58 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
> **Stage 1: Proposal**
>
> **Stage 1: Proposal**
>
> This spec is under active development. For more information, please see the [Roadmap](ROADMAP.md) or [how to get involved](INTERESTED_DEVELOPERS.md).

---
Expand Down Expand Up @@ -83,13 +83,29 @@ It is recommended to end the path component of the URL with `/graphql`, for exam

# Serialization Format

Similar to the GraphQL specification this specification does not require a specific serialization format.
For consistency and ease of notation, examples of the response are given in JSON throughout the spec.
The GraphQL specification allows for many [serialization formats to be implemented](https://spec.graphql.org/June2018/#sec-Serialization-Format). Servers and clients over HTTP MUST support JSON and MAY support other, additional serialization formats.

## Content Types

The following are the officially recognized GraphQL content types to designate encoding JSON over HTTP.

| Name | Description |
| `application/graphql+json` | Required
| `application/json` | To support legacy clients

A server MUST support requests from clients with HTTP header `Content-Type: application/graphql+json` indicating that the body of the request is a JSON document with a GraphQL request. A server must indicate the content type of the response with a `Content-Type` header. This default value should be `Content-Type: application/graphql+json` indicating that the response is a valid JSON document containing at least one of the `data` or `errors` as a top-level attribute.

A server MAY support requests from clients with other content types.

A client MUST handle receiving responses with HTTP header `Content-Type: application/graphql+json` since any compliant server must support this type.

This header MAY include encoding information (e.g. `Content-Type: application/graphql+json; charset=utf-8`)

# Request

The GraphQL HTTP server SHOULD handle the HTTP GET and POST methods.
Additionally, GraphQL MAY be used in combination with other HTTP request methods.
A server MUST accept POST requests, and MAY accept other HTTP methods, such as GET.

A server SHOULD handle both GET and POST requests.
Copy link
Contributor

Choose a reason for hiding this comment

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

There is ambiguity here in that one line states that a server MUST accept either GET or POST requests and then that it should handle both.

Copy link
Contributor

Choose a reason for hiding this comment

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

It also seemed strange to me.

Copy link
Contributor

Choose a reason for hiding this comment

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

What is the difference between accept and handle?


## Request Parameters

Expand All @@ -99,18 +115,28 @@ A request for execution should contain the following request parameters:
* `operationName` - [*Optional*]: The name of the Operation in the Document to execute.
* `variables` - [*Optional*]: Values for any Variables defined by the Operation.

Note: Be aware that `query` is a misleading name as it can contain a string describing the operation that may be either a query, a mutation or a subscription.

Note: depending on the serialization format used, values of the aforementioned parameters can be
encoded differently but their names and semantics must stay the same.

Note: specifying `null` in JSON (or equivalent values in other formats) as values for optional request parameters is equivalent to not specifying them at all.

## GET

For HTTP GET requests, the query parameters should be provided in the query component of the request URL in the form of
For HTTP GET requests, the query parameters MUST be provided in the query component of the request URL in the form of
Copy link
Contributor

Choose a reason for hiding this comment

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

I totally agree that this should be changed to MUST. I cannot imagine what could be done with a GET request that contained no operation.

`key=value` pairs with `&` symbol as a separator and both the key and value should have their "reserved" characters percent-encoded as specified in [section 2 of RFC3986](https://tools.ietf.org/html/rfc3986#section-2).
The unencoded value of the `variables` parameter should be represented as a JSON-encoded string.
The unencoded value of the `variables` parameter MUST be represented as a URL-encoded JSON string.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
The unencoded value of the `variables` parameter MUST be represented as a URL-encoded JSON string.
The value of the `variables` parameter MUST be represented as a URL-encoded JSON object, with a name-value pair for each variable and its value.

This is what the example shows: the unencoded/decoded value is a JSON object, the actual/encoded value is a URL-encoded JSON object. No double-encoding.

Copy link
Contributor

Choose a reason for hiding this comment

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

nit pick (not blocking): JSON is a string (the N is for notation).

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm still confused by The unencoded value ... represented as a URL-encoded ....

Does this mean that I

  • first have to translate the variables object into JSON,
  • then URL-encode that JSON to get an un-encoded parameter value,
  • and then again percent-encode the un-encoded parameter value before sending it in the HTTP request?

I hope percent/URL-encoding happens only once.


GET requests must ONLY be used for executing queries and MUST NOT be used for mutations or subscriptions.

Servers MUST return an _Error response_ if a GET request includes a `query` and `operationName` (if present) describing an operation other than a query, such as a mutation or subscription.

Clients MUST NOT send GET requests for non-query operations.
Copy link
Contributor

Choose a reason for hiding this comment

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

Are these lines similar in meaning?

GET requests must ONLY be used for executing queries and MUST NOT be used for mutations or subscriptions.

and

Clients MUST NOT send GET requests for non-query operations.

If not, should we provide an example of a non-query operation?


Clients SHOULD NOT send a `Content-Type` header on a GET request.

GET requests can be used for executing ONLY queries. If the values of `query` and `operationName` indicates that a non-query operation is to be executed, the server should immediately respond with an error status code, and halt execution.
### Example

For example, if we wanted to execute the following GraphQL query:

Expand All @@ -121,12 +147,15 @@ query ($id: ID!) {
}
}
```

With the following query variables:
``` graphql

```json
{
id:"QVBJcy5ndXJ1"
"id": "QVBJcy5ndXJ1"
}
```

This request could be sent via an HTTP GET as follows:

```
Expand All @@ -137,10 +166,13 @@ Note: `query` and `operationName` parameters are encoded as raw strings in the q

## POST

A standard GraphQL POST request should have a body which contains values of the request parameters encoded according to
the value of `Content-Type` header.
A GraphQL POST request instructs the server to perform a query, mutation or subscription operation. A GraphQL POST request MUST have a body which contains values of the request parameters encoded according to the value of `Content-Type` header of the request.

A client MUST include a `Content-Type` with a POST request.

### Example

For example if the `Content-Type` is `application/json` then the request body may be:
Given a POST request with a content type of `application/graphql+json` here is an example request body:

```json
{
Expand All @@ -149,18 +181,27 @@ For example if the `Content-Type` is `application/json` then the request body ma
}
```

Note: both query and mutation operations can be sent over POST requests.

# Response

When a GraphQL server receives a request, it must return a well‐formed response. The servers
When a GraphQL server receives a request, it must return a well‐formed response. The server's
response describes the result of executing the requested operation if successful, and describes
any errors encountered during the request.

## Body

If the server's response contains a body it should follow the requirements for [GraphQL response](https://graphql.github.io/graphql-spec/June2018/#sec-Response).

A server MUST return a `Content-Type` HTTP Header with a value of a valid GraphQL content type. By default the response MUST be serialized as JSON and MUST include a "Content-Type: application/graphql+json` header.

If another content type is preferable to a client, it MAY include an `Accept` HTTP header listing other acceptable content types in order of preference. In this case a client SHOULD include `application/graphql+json` in the list, according to their preferred priority.

If no `Accept` header is given, the server MUST respond with a content type of `application/graphql+json`.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Perhaps weaken this statement and add non-normative note suggesting that this default be application/graphql+json to support legacy clients, to allow more wider implementations.


The server MUST respect the given `Accept` header and attempt to encode the respond in the first supported content type listed. According to 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 content type in the `Accept` HTTP header, the server MAY choose to respond in one of several ways. The server MUST either:

1. Disregard the `Accept` header and respond with the default content type of `application/graphql+json`, specifying this in the `Content-Type` header; OR
2. Respond with a `406 Not Acceptable` status code

Note: For any non-2XX response, the client should not rely on the body to be in GraphQL format since the source of the response
may not be the GraphQL server but instead some intermediary such as API gateways, firewalls, etc.

Expand Down