-
Notifications
You must be signed in to change notification settings - Fork 66
Provide clarifications on content type and serialization #83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
635a689
8ab3573
e143f3c
28f82d4
312a0de
0c9f922
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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). | ||||||
|
|
||||||
| --- | ||||||
|
|
@@ -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. | ||||||
|
|
||||||
| ## Request Parameters | ||||||
|
|
||||||
|
|
@@ -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 | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
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.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit pick (not blocking): JSON is a string (the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm still confused by Does this mean that I
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. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are these lines similar in meaning?
and
If not, should we provide an example of a |
||||||
|
|
||||||
| 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: | ||||||
|
|
||||||
|
|
@@ -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: | ||||||
|
|
||||||
| ``` | ||||||
|
|
@@ -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 | ||||||
| { | ||||||
|
|
@@ -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 server’s | ||||||
| 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`. | ||||||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. | ||||||
|
|
||||||
|
|
||||||
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
acceptandhandle?