Skip to content

Align transports with GraphQL over HTTP specification #1117

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

Closed
4 tasks done
bclozel opened this issue Jan 31, 2025 · 0 comments
Closed
4 tasks done

Align transports with GraphQL over HTTP specification #1117

bclozel opened this issue Jan 31, 2025 · 0 comments
Assignees
Labels
in: web Issues related to web handling type: enhancement A general enhancement
Milestone

Comments

@bclozel
Copy link
Member

bclozel commented Jan 31, 2025

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.

@bclozel bclozel added in: web Issues related to web handling type: enhancement A general enhancement labels Jan 31, 2025
@bclozel bclozel added this to the 1.4.x milestone Jan 31, 2025
@bclozel bclozel self-assigned this Jan 31, 2025
@bclozel bclozel modified the milestones: 1.4.x, 1.4.0-M1 Feb 4, 2025
bclozel added a commit that referenced this issue Feb 5, 2025
Prior to this commit, the `GraphQlHttpHandler` implementations for MVC
and WebFlux would support the HTTP transport protocol for servers.
They would align with the well-known GraphQL behavior, using HTTP as a
transport and always using HTTP 200 OK as response status.

The new GraphQL over HTTP specification changes that, and requires
servers to respond with HTTP 4xx/5xx statuses when an error occurs
before the GraphQL request execution: for example, if the JSON document
cannot be parsed, or the GraphQL document is invalid.

This commit introduces a new "standard mode" option on HTTP transports
to follow this new requirement. Because this is a breaking change for
GraphQL clients, this mode is opt-in only for now.

See gh-1117
bclozel added a commit that referenced this issue Feb 12, 2025
This commit adapts the GraphQlClient HTTP transports (async and sync) to
accept 4xx responses if the response content type is
"application/graphql-response+json".

This allows the client to support the "GraphQL over HTTP" specification.
This commit adds a new test suite to check compatibility against this
spec.

See gh-1117
bclozel added a commit that referenced this issue Feb 13, 2025
This commit renames and changes the behavior of the configuration option
on `GraphQlHttpHandler` implementations. The
`setHttpOkOnValidationErrors` option is `false` by default and is
introduced as a deprecated method right away. Our goal here is to fade
out this option as soon as possible the traditional behavior for
"application/graphql-response+json" media types.

See gh-1117
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues related to web handling type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

1 participant