Adapt to GraphQL over HTTP spec changes

As of graphql/graphql-over-http#215, the official media type for GraphQL
HTTP responses is now `"application/graphql-response+json"` instead of
`"application/graphql+json"`. The latter is now deprecated and support
will be removed in the future.

This commit now favors the new media type.
HTTP Clients are still supposed to send requests with the
`"application/json"` content type.

Closes gh-563
This commit is contained in:
Brian Clozel
2022-12-05 14:47:51 +01:00
parent eb9b1f308d
commit 573e89987f
6 changed files with 30 additions and 13 deletions

View File

@@ -44,6 +44,10 @@ final class HttpGraphQlTransport implements GraphQlTransport {
private static final ParameterizedTypeReference<Map<String, Object>> MAP_TYPE =
new ParameterizedTypeReference<Map<String, Object>>() {};
// To be removed in favor of Framework's MediaType.APPLICATION_GRAPHQL_RESPONSE
private static final MediaType APPLICATION_GRAPHQL_RESPONSE =
new MediaType("application", "graphql-response+json");
private final WebClient webClient;
@@ -65,10 +69,11 @@ final class HttpGraphQlTransport implements GraphQlTransport {
@Override
@SuppressWarnings("removal")
public Mono<GraphQlResponse> execute(GraphQlRequest request) {
return this.webClient.post()
.contentType(this.contentType)
.accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_GRAPHQL)
.accept(MediaType.APPLICATION_JSON, APPLICATION_GRAPHQL_RESPONSE, MediaType.APPLICATION_GRAPHQL)
.bodyValue(request.toMap())
.retrieve()
.bodyToMono(MAP_TYPE)

View File

@@ -43,11 +43,16 @@ public class GraphQlHttpHandler {
private static final Log logger = LogFactory.getLog(GraphQlHttpHandler.class);
// To be removed in favor of Framework's MediaType.APPLICATION_GRAPHQL_RESPONSE
private static final MediaType APPLICATION_GRAPHQL_RESPONSE =
new MediaType("application", "graphql-response+json");
private static final ParameterizedTypeReference<Map<String, Object>> MAP_PARAMETERIZED_TYPE_REF =
new ParameterizedTypeReference<Map<String, Object>>() {};
@SuppressWarnings("removal")
private static final List<MediaType> SUPPORTED_MEDIA_TYPES =
Arrays.asList(MediaType.APPLICATION_GRAPHQL, MediaType.APPLICATION_JSON);
Arrays.asList(APPLICATION_GRAPHQL_RESPONSE, MediaType.APPLICATION_JSON, MediaType.APPLICATION_GRAPHQL);
private final WebGraphQlHandler graphQlHandler;

View File

@@ -55,8 +55,13 @@ public class GraphQlHttpHandler {
private static final ParameterizedTypeReference<Map<String, Object>> MAP_PARAMETERIZED_TYPE_REF =
new ParameterizedTypeReference<Map<String, Object>>() {};
// To be removed in favor of Framework's MediaType.APPLICATION_GRAPHQL_RESPONSE
private static final MediaType APPLICATION_GRAPHQL_RESPONSE =
new MediaType("application", "graphql-response+json");
@SuppressWarnings("removal")
private static final List<MediaType> SUPPORTED_MEDIA_TYPES =
Arrays.asList(MediaType.APPLICATION_GRAPHQL, MediaType.APPLICATION_JSON);
Arrays.asList(APPLICATION_GRAPHQL_RESPONSE, MediaType.APPLICATION_JSON, MediaType.APPLICATION_GRAPHQL);
private final IdGenerator idGenerator = new AlternativeJdkIdGenerator();

View File

@@ -189,13 +189,14 @@ public class WebGraphQlClientBuilderTests {
@Test
void contentTypeOverride() {
MediaType testMediaType = new MediaType("application", "graphql-request+json");
HttpBuilderSetup setup = new HttpBuilderSetup();
setup.initBuilder().header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_GRAPHQL_VALUE).build()
setup.initBuilder().header(HttpHeaders.CONTENT_TYPE, "application/graphql-request+json").build()
.document(DOCUMENT).execute().block(TIMEOUT);
WebGraphQlRequest request = setup.getActualRequest();
assertThat(request.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_GRAPHQL);
assertThat(request.getHeaders().getContentType()).isEqualTo(testMediaType);
}

View File

@@ -64,12 +64,12 @@ public class GraphQlHttpHandlerTests {
@Test
void shouldProduceApplicationGraphQl() {
MockServerHttpRequest httpRequest = MockServerHttpRequest.post("/")
.contentType(MediaType.APPLICATION_GRAPHQL).accept(MediaType.APPLICATION_GRAPHQL).build();
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_GRAPHQL_RESPONSE).build();
MockServerHttpResponse httpResponse = handleRequest(
httpRequest, this.greetingHandler, Collections.singletonMap("query", "{greeting}"));
assertThat(httpResponse.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_GRAPHQL);
assertThat(httpResponse.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_GRAPHQL_RESPONSE);
}
@Test
@@ -90,7 +90,8 @@ public class GraphQlHttpHandlerTests {
.toHttpHandlerWebFlux();
MockServerHttpRequest httpRequest = MockServerHttpRequest.post("/")
.contentType(MediaType.APPLICATION_GRAPHQL).accept(MediaType.APPLICATION_GRAPHQL).acceptLanguageAsLocales(Locale.FRENCH).build();
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_GRAPHQL_RESPONSE)
.acceptLanguageAsLocales(Locale.FRENCH).build();
MockServerHttpResponse httpResponse = handleRequest(
httpRequest, handler, Collections.singletonMap("query", "{greeting}"));
@@ -106,7 +107,7 @@ public class GraphQlHttpHandlerTests {
.toHttpHandlerWebFlux();
MockServerHttpRequest httpRequest = MockServerHttpRequest.post("/")
.contentType(MediaType.APPLICATION_GRAPHQL).accept(MediaType.APPLICATION_GRAPHQL).build();
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_GRAPHQL_RESPONSE).build();
MockServerHttpResponse httpResponse = handleRequest(
httpRequest, handler, Collections.singletonMap("query", "{showId}"));

View File

@@ -64,9 +64,9 @@ public class GraphQlHttpHandlerTests {
@Test
void shouldProduceApplicationGraphQl() throws Exception {
MockHttpServletRequest servletRequest = createServletRequest("{\"query\":\"{ greeting }\"}", MediaType.APPLICATION_GRAPHQL_VALUE);
MockHttpServletRequest servletRequest = createServletRequest("{\"query\":\"{ greeting }\"}", MediaType.APPLICATION_GRAPHQL_RESPONSE_VALUE);
MockHttpServletResponse servletResponse = handleRequest(servletRequest, this.greetingHandler);
assertThat(servletResponse.getContentType()).isEqualTo(MediaType.APPLICATION_GRAPHQL_VALUE);
assertThat(servletResponse.getContentType()).isEqualTo(MediaType.APPLICATION_GRAPHQL_RESPONSE_VALUE);
}
@Test
@@ -81,7 +81,7 @@ public class GraphQlHttpHandlerTests {
GraphQlHttpHandler handler = GraphQlSetup.schemaContent("type Query { greeting: String }")
.queryFetcher("greeting", (env) -> "Hello in " + env.getLocale())
.toHttpHandler();
MockHttpServletRequest servletRequest = createServletRequest("{\"query\":\"{ greeting }\"}", MediaType.APPLICATION_GRAPHQL_VALUE);
MockHttpServletRequest servletRequest = createServletRequest("{\"query\":\"{ greeting }\"}", MediaType.APPLICATION_GRAPHQL_RESPONSE_VALUE);
LocaleContextHolder.setLocale(Locale.FRENCH);
try {
@@ -101,7 +101,7 @@ public class GraphQlHttpHandlerTests {
.queryFetcher("showId", (env) -> env.getExecutionId().toString())
.toHttpHandler();
MockHttpServletRequest servletRequest = createServletRequest("{\"query\":\"{ showId }\"}", MediaType.APPLICATION_GRAPHQL_VALUE);
MockHttpServletRequest servletRequest = createServletRequest("{\"query\":\"{ showId }\"}", MediaType.APPLICATION_GRAPHQL_RESPONSE_VALUE);
MockHttpServletResponse servletResponse = handleRequest(servletRequest, handler);
DocumentContext document = JsonPath.parse(servletResponse.getContentAsString());