Description
This change has been requested in #1113, #568 and #783 in several forms.
This umbrella issue will consider changes in Spring for GraphQL to better align the HTTP transports behavior with the GraphQL over HTTP specification for the "application/graphql-response+json" media type. The implementation is quite close, but we just need a few changes.
In summary, the behavior difference we need to address between "application/json"
and "application/graphql-response+json"
response media types is about HTTP response status codes. An HTTP request sent to a GraphQL endpoint is processed in several phases like: authentication, JSON parsing, GraphQL document parsing, GraphQL document validation, GraphQL request execution. Depending on when an error occurs, the HTTP response status behavior will differ:
Error Phase | application/json | application/graphql-response+json |
---|---|---|
JSON parsing | HTTP 400 | HTTP 400 |
document parsing | HTTP 200 | HTTP 400 |
document validation | HTTP 200 | HTTP 400 |
request execution | HTTP 200 | HTTP 200 |
Also, the "data"
key in the response document is only present (but can be null) once we enter the execution phase.
Right now, Spring for GraphQL is using the "application/graphql-response+json"
media type by default when clients don't request explicitly "application/json"
in the Accept:
request header. Because we mostly already align with the spec, we will need to introduce a "fallback option" to re-enable the previous behavior in case this is a problem for existing clients. We will introduce this option as @Deprecated
right away as we'll need to phase it out as soon as possible.
This change will mostly impact GraphQL clients that expect an HTTP 200 OK response before they consider reading the body as a GraphQL JSON response. For some early error cases, such clients will also need to consider HTTP 400 Bad Request as long as the response content type is "application/graphql-response+json"
.
To resolve this issue, we should consider several tasks:
- Align the MVC variant of the HTTP transport and write dedicated integration tests. Offer this behavior as an opt-in feature.
- Align the WebFlux variant of the HTTP transport and write dedicated integration tests. Offer this behavior as an opt-in feature.
- Update the
GraphQLClient
to be more flexible and decode GraphQL responses even if the server responds with a 4xx response status. - Document this behavior difference and guide GraphQL clients in our reference documentation.
The main driver for this change is to help HTTP tooling to better identify error cases in GraphQL HTTP exchanges without having to parse response bodies. Many error cases will still appear as "200 OK" responses, if partial data or no data at all was sent in the response. In that sense, platforms will still need an observabily solution; Spring for GraphQL does provide comprehensive metrics and traces.