-
Notifications
You must be signed in to change notification settings - Fork 66
Drop backwards compatibility #370
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
base: main
Are you sure you want to change the base?
Changes from 4 commits
611d794
85ae1da
7fc20fb
fceb342
b50a0c6
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 |
|---|---|---|
|
|
@@ -183,10 +183,12 @@ using the JSON encoding for GraphQL requests: | |
|
|
||
| And for a _GraphQL response_: | ||
|
|
||
| | Name | Description | | ||
| | ----------------------------------- | ------------------------------------------------------------------ | | ||
| | `application/graphql-response+json` | The preferred type for server responses; better HTTP compatibility | | ||
| | `application/json` | An alternative type for responses (to support legacy clients) | | ||
| | Name | Description | | ||
| | ----------------------------------- | --------------------------------------- | | ||
| | `application/graphql-response+json` | The preferred type for server responses | | ||
|
|
||
| Note: Servers MAY additionally support `application/json` as a response media | ||
| type. | ||
|
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. Does it make sense to link somewhere that might specify what the behavior should be? (i.e. non-200x status codes unacceptable, etc.). We (the Apollo Client team) used this document to throw errors properly for But maybe thats the point of this change? 🤔
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. Would it be OK to put that as markdown file in this repo? 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 fine with that too! I'm mostly looking for it written down somewhere so that client libraries know what to expect. 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. Yup, keeping that somewhere for reference would be greatly appreciated. It would also be great if that document could show the |
||
|
|
||
| For details of the shapes of these JSON payloads, please see | ||
| [Request](#sec-Request) and [Response](#sec-Response). | ||
|
|
@@ -249,28 +251,12 @@ 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). | ||
|
|
||
| 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 | ||
| valid GraphQL response under a media type of its choosing). To ensure your | ||
| client gets something useful, it needs to indicate the media types it supports. | ||
|
|
||
| The client MUST include the media type `application/graphql-response+json` in | ||
| the `Accept` header. | ||
|
|
||
| If the client knows that the server supports | ||
| `application/graphql-response+json`, it is RECOMMENDED that the client set the | ||
| `Accept` header to `application/graphql-response+json`. Otherwise, to maximize | ||
| compatibility the client SHOULD include the media type `application/json` in the | ||
| `Accept` header and it is RECOMMENDED that the client set the `Accept` header to | ||
| `application/graphql-response+json, application/json;q=0.9`. | ||
|
|
||
| Note: The `q=0.9` parameter tells content negotiation that `application/json` | ||
| should only be used if `application/graphql-response+json` is not supported. | ||
|
|
||
| The `application/graphql-response+json` media type adds improved support for | ||
| HTTP status codes compared to the legacy `application/json` media type. When | ||
| accepting both media types, the client SHOULD indicate it prefers | ||
| `application/graphql-response+json` over `application/json`. | ||
| The client MAY additionally include the media type `application/json` in the | ||
| `Accept` header. When accepting both media types, the client SHOULD indicate it | ||
| prefers `application/graphql-response+json` over `application/json`. | ||
|
martinbonnin marked this conversation as resolved.
Outdated
|
||
|
|
||
| ## GET | ||
|
|
||
|
|
@@ -461,34 +447,14 @@ one of the media types it has requested, hence `406 Not Acceptable` being the | |
| recommended response. However, the server authors may know better about the | ||
| specific clients consuming their endpoint, thus both approaches are permitted. | ||
|
|
||
| A server MUST support responses using at least one of the official GraphQL | ||
| response media types. | ||
|
|
||
| For maximal compatibility, a _server_ SHOULD support using both the | ||
| `application/json` and the `application/graphql-response+json` media types for | ||
| responses. | ||
| A _server_ MUST support responses using the `application/graphql-response+json` | ||
| media type. | ||
|
|
||
| Each newly created or updated GraphQL _server_ SHOULD support responses using | ||
| the `application/graphql-response+json` media type. | ||
| A server MAY additionally support the `application/json` response media type. | ||
|
|
||
| :: A _legacy server_ is a _server_ that does not support responses using the | ||
| `application/graphql-response+json` media type. | ||
|
|
||
| Note: Prior to this specification, the media type `application/json` was in wide | ||
| use for the HTTP response payload type. Unfortunately this means clients cannot | ||
| trust responses from the server that do not use an HTTP 2xx status code (since | ||
| these replies may come from non-compliant HTTP servers or proxies somewhere in | ||
| the request chain). For this reason, this specification introduces the | ||
| `application/graphql-response+json` media type on responses; however support for | ||
| this new media type is optional to allow legacy servers time to transition. | ||
|
|
||
| A server MAY choose to not support the `application/json` response media type, | ||
| however doing so may limit compatibility with existing clients, so it is only | ||
| recommended when creating a new GraphQL service. | ||
|
|
||
| Note: Servers may wish to enforce that clients use the | ||
| `application/graphql-response+json` data type so that related HTTP tooling may | ||
| utilize the HTTP status codes of responses without having to be GraphQL-aware. | ||
| Note: Servers may wish to only support the `application/graphql-response+json` | ||
| media type so that related HTTP tooling may utilize the HTTP status codes of | ||
| responses without having to be GraphQL-aware. | ||
|
|
||
| ## Validation | ||
|
|
||
|
|
@@ -515,144 +481,12 @@ execution regardless of validation errors. | |
| ## Status Codes | ||
|
|
||
| In case of errors that completely prevent the generation of a well-formed | ||
| _GraphQL response_, the server SHOULD respond with the appropriate status code | ||
| _GraphQL response_, the server MUST respond with the appropriate status code | ||
| depending on the concrete error condition, and MUST NOT respond with a `2xx` | ||
| status code when using the `application/graphql-response+json` media type. | ||
| status code. | ||
|
|
||
| Note: Typically the appropriate status code will be `400` (Bad Request). | ||
|
|
||
| Note: This rule is "should" to maintain compatibility with legacy servers which | ||
| can return 200 status codes even when this type of error occurs, but only when | ||
| not using the `application/graphql-response+json` media type. | ||
|
|
||
| Otherwise, the status codes depends on the media type with which the GraphQL | ||
| response will be served: | ||
|
|
||
| ### application/json | ||
|
|
||
| This section only applies when the response body is to use the | ||
| `application/json` media type. | ||
|
|
||
| The server SHOULD use the `200` status code for every response to a well-formed | ||
| _GraphQL-over-HTTP request_, independent of any _GraphQL request error_ or | ||
| _GraphQL field error_ raised. | ||
|
|
||
| If the response uses a non-`200` status code then the client MUST NOT rely on | ||
| the body to be a well-formed _GraphQL response_. | ||
|
|
||
| Note: A status code in the `4xx` or `5xx` ranges or status code `203` (and maybe | ||
| others) could originate from an intermediary; since the client cannot determine | ||
| if an `application/json` response with arbitrary status code is a well-formed | ||
| _GraphQL response_ (because it cannot trust the source) the server must use | ||
| `200` status code to guarantee to the client that the response has not been | ||
| generated or modified by an intermediary. See | ||
| [processing a response](#sec-Processing-a-response) for more details. | ||
|
|
||
| If the _GraphQL response_ contains a non-null {data} entry then the server MUST | ||
| use the `200` status code. | ||
|
|
||
| Note: This indicates that no _GraphQL request error_ was raised, though one or | ||
| more _GraphQL field error_ may have been raised this is still a successful | ||
| execution - see "partial response" in the GraphQL specification. | ||
|
|
||
| The server SHOULD NOT use a `4xx` or `5xx` status code for a response to a | ||
| well-formed _GraphQL-over-HTTP request_. | ||
|
|
||
| Note: For compatibility with legacy servers, this specification allows the use | ||
| of `4xx` or `5xx` status codes for a failed well-formed _GraphQL-over-HTTP | ||
| request_ where the response uses the `application/json` media type, but it is | ||
| strongly discouraged. To use `4xx` and `5xx` status codes in these situations, | ||
| please use the `application/graphql-response+json` media type. | ||
|
|
||
| If the URL is not used for other purposes, the server SHOULD use a `4xx` status | ||
| code to respond to a request that is not a well-formed _GraphQL-over-HTTP | ||
| request_. | ||
|
|
||
| Note: For compatibility with legacy servers, this specification allows the use | ||
| of `2xx` or `5xx` status codes when responding to invalid requests using the | ||
| `application/json` media type, but it is strongly discouraged. | ||
|
|
||
| Note: URLs that enable GraphQL requests may enable other types of requests - see | ||
| the [URL](#url) section. | ||
|
|
||
| #### Examples | ||
|
|
||
| The following examples provide guidance on how to deal with specific error cases | ||
| when using the `application/json` media type to encode the response body: | ||
|
|
||
| ##### JSON parsing failure | ||
|
|
||
| For example a POST request body of `NONSENSE` or `{"query":` (note: invalid | ||
| JSON). | ||
|
|
||
| Requests that the server cannot interpret SHOULD result in status code `400` | ||
| (Bad Request). | ||
|
|
||
| ##### Invalid parameters | ||
|
|
||
| For example a POST request body of `{"qeury": "{__typename}"}` (note: typo) or | ||
| `{"query": "query Q ($i:Int!) { q(i: $i) }", "variables": [7]}` (note: invalid | ||
| shape for `variables`). | ||
|
|
||
| A request that does not constitute a well-formed _GraphQL-over-HTTP request_ | ||
| SHOULD result in status code `400` (Bad Request). | ||
|
|
||
| ##### Document parsing failure | ||
|
|
||
| For example a POST request body of `{"query": "{"}`. | ||
|
|
||
| Requests where the _GraphQL document_ cannot be parsed SHOULD result in status | ||
| code `200` (Okay). | ||
|
|
||
| ##### Document validation failure | ||
|
|
||
| If a request fails to pass _GraphQL validation_, the server SHOULD NOT execute | ||
| the request and SHOULD return a status code of `200` (Okay). | ||
|
|
||
| ##### Operation cannot be determined | ||
|
|
||
| If [GetOperation()](<https://spec.graphql.org/draft/#GetOperation()>) raises a | ||
| _GraphQL request error_, the server SHOULD NOT execute the request and SHOULD | ||
| return a status code of `200` (Okay). | ||
|
|
||
| ##### Variable coercion failure | ||
|
|
||
| If | ||
| [CoerceVariableValues()](<https://spec.graphql.org/draft/#CoerceVariableValues()>) | ||
| raises a _GraphQL request error_, the server SHOULD NOT execute the request and | ||
| SHOULD return a status code of `200` (Okay). | ||
|
|
||
| For example the well-formed GraphQL-over-HTTP request: | ||
|
|
||
| ```json | ||
| { | ||
| "query": "query getItemName($id: ID!) { item(id: $id) { id name } }", | ||
| "variables": { "id": null } | ||
| } | ||
| ``` | ||
|
|
||
| would fail variable coercion as the value for `id` would fail to satisfy the | ||
| query document's expectation that `id` is non-null. | ||
|
|
||
| ##### Field errors encountered during execution | ||
|
|
||
| If the operation is executed and no _GraphQL request error_ is raised then the | ||
| server SHOULD respond with a status code of `200` (Okay). This is the case even | ||
| if a _GraphQL field error_ is raised during | ||
| [GraphQL's ExecuteQuery()](<https://spec.graphql.org/draft/#ExecuteQuery()>) or | ||
| [GraphQL's ExecuteMutation()](<https://spec.graphql.org/draft/#ExecuteMutation()>). | ||
|
|
||
| <!-- | ||
| When we add support for subscriptions, | ||
| [GraphQL's MapSourceToResponseEvent()](<https://spec.graphql.org/draft/#MapSourceToResponseEvent()>) | ||
| should be added to the above. | ||
| --> | ||
|
|
||
| ### application/graphql-response+json | ||
|
|
||
| This section only applies when the response body is to use the | ||
| `application/graphql-response+json` media type. | ||
|
|
||
| If the _GraphQL response_ contains the {data} entry and it is not {null}, then | ||
| the server MUST reply with a `2xx` status code and SHOULD reply with `200` | ||
| status code. | ||
|
|
@@ -690,27 +524,25 @@ pass validation, then the server SHOULD reply with `400` status code. | |
| If the client is not permitted to issue the GraphQL request then the server | ||
| SHOULD reply with `403`, `401` or similar appropriate status code. | ||
|
|
||
| Note: When the response media type is `application/graphql-response+json`, | ||
| clients can rely on the response being a well-formed _GraphQL response_ | ||
| Note: Clients can rely on the response being a well-formed _GraphQL response_ | ||
| regardless of the status code. Intermediary servers may use the status code to | ||
| determine the status of the _GraphQL response_ without needing to process the | ||
| response body. | ||
|
|
||
| #### Examples | ||
| ### Examples | ||
|
|
||
| The following examples provide guidance on how to deal with specific error cases | ||
| when using the `application/graphql-response+json` media type to encode the | ||
| response body: | ||
| The following examples provide guidance on how to deal with specific error | ||
| cases: | ||
|
|
||
| ##### JSON parsing failure | ||
| #### JSON parsing failure | ||
|
|
||
| For example a POST request body of `NONSENSE` or `{"query":` (note: invalid | ||
| JSON). | ||
|
|
||
| Requests that the server cannot interpret should result in status code `400` | ||
| (Bad Request). | ||
|
|
||
| ##### Invalid parameters | ||
| #### Invalid parameters | ||
|
|
||
| For example a POST request body of `{"qeury": "{__typename}"}` (note: typo) or | ||
| `{"query": "query Q ($i:Int!) { q(i: $i) }", "variables": [7]}` (note: invalid | ||
|
|
@@ -719,32 +551,32 @@ shape for `variables`). | |
| A request that does not constitute a well-formed _GraphQL-over-HTTP request_ | ||
| SHOULD result in status code `400` (Bad Request). | ||
|
|
||
| ##### Document parsing failure | ||
| #### Document parsing failure | ||
|
|
||
| For example a POST request body of `{"query": "{"}`. | ||
|
|
||
| Requests where the _GraphQL document_ cannot be parsed should result in status | ||
| code `400` (Bad Request). | ||
|
|
||
| ##### Document validation failure | ||
| #### Document validation failure | ||
|
|
||
| If a request fails _GraphQL validation_, the server SHOULD return a status code | ||
| of `400` (Bad Request) without proceeding to GraphQL execution. | ||
|
|
||
| ##### Operation cannot be determined | ||
| #### Operation cannot be determined | ||
|
|
||
| If [GetOperation()](<https://spec.graphql.org/draft/#GetOperation()>) raises a | ||
| _GraphQL request error_, the server SHOULD NOT execute the request and SHOULD | ||
| return a status code of `400` (Bad Request). | ||
|
|
||
| ##### Variable coercion failure | ||
| #### Variable coercion failure | ||
|
|
||
| If | ||
| [CoerceVariableValues()](<https://spec.graphql.org/draft/#CoerceVariableValues()>) | ||
| raises a _GraphQL request error_, the server SHOULD NOT execute the request and | ||
| SHOULD return a status code of `400` (Bad Request). | ||
|
|
||
| ##### Field errors encountered during execution | ||
| #### Field errors encountered during execution | ||
|
|
||
| If the operation is executed and no _GraphQL request error_ is raised then the | ||
| server SHOULD respond with a status code of `200` (Okay). This is the case even | ||
|
|
@@ -768,23 +600,6 @@ response; it still indicates successful execution. | |
| This section of the specification is non-normative, even where the words and | ||
| phrases specified in RFC2119 are used. | ||
|
|
||
| ## Processing a response | ||
|
|
||
| In some cases, the response received by a client may not originate from a | ||
| GraphQL service, but instead from an intermediary—such as an API gateway, proxy, | ||
| firewall or other middleware—that does not implement this specification. Such an | ||
| intermediary might produce the response to indicate an error, returning a | ||
| response with `4xx` or `5xx` status code and potentially using the standard | ||
| `application/json` media type to encode the reason for the error. Such a | ||
| response is unlikely to be a valid GraphQL response. | ||
|
|
||
| For this reason, a client application can rely on the response being a | ||
| well-formed _GraphQL response_ only if at least one of the following conditions | ||
| is met: | ||
|
|
||
| - the response media type is `application/graphql-response+json`, or | ||
| - the status code is `200`. | ||
|
|
||
| ## Security | ||
|
|
||
| This specification focuses solely on the intersection of GraphQL and HTTP. | ||
|
|
||
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.
Does it still makes sense to use a table, now that there's only one row (same for the table for requests, above).
Also is "preferred" still the right word?