diff --git a/build.gradle b/build.gradle
index 4dd9621d..e4b702d8 100644
--- a/build.gradle
+++ b/build.gradle
@@ -13,8 +13,8 @@ subprojects {
ext {
graphqlJavaVersion = "15.0"
- springVersion = "5.1.7.RELEASE"
- springBootVersion = "2.1.5.RELEASE"
+ springVersion = "5.2.8.RELEASE"
+ springBootVersion = "2.3.2.RELEASE"
jacksonVersion = "2.9.8"
assertJVersion = "3.11.1"
}
@@ -42,7 +42,7 @@ subprojects {
}
task myWrapper(type: Wrapper) {
- gradleVersion = '4.10.2'
+ gradleVersion = '6.5.1'
distributionUrl = "https://services.gradle.org/distributions/gradle-${gradleVersion}-all.zip"
}
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index d76b502e..ac33e994 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/graphql-java-spring-boot-starter-webmvc/build.gradle b/graphql-java-spring-boot-starter-webmvc/build.gradle
index c37e06b7..8c2fc114 100644
--- a/graphql-java-spring-boot-starter-webmvc/build.gradle
+++ b/graphql-java-spring-boot-starter-webmvc/build.gradle
@@ -1,7 +1,7 @@
description = "GraphQL Java Spring Boot starter Webmvc"
dependencies {
- compile "org.springframework.boot:spring-boot-autoconfigure:$springBootVersion"
- compile project(':graphql-java-spring-webmvc')
+ implementation "org.springframework.boot:spring-boot-autoconfigure:$springBootVersion"
+ implementation project(':graphql-java-spring-webmvc')
testCompile "org.springframework.boot:spring-boot-starter-test:$springBootVersion"
testCompile "org.springframework.boot:spring-boot-starter-web:$springBootVersion"
diff --git a/graphql-java-spring-webmvc/build.gradle b/graphql-java-spring-webmvc/build.gradle
index c9773262..2fe0c08a 100644
--- a/graphql-java-spring-webmvc/build.gradle
+++ b/graphql-java-spring-webmvc/build.gradle
@@ -1,15 +1,17 @@
description = "GraphQL Java Spring Webmvc integration"
-dependencies {
- compile "org.springframework:spring-webmvc:$springVersion"
- compile "org.springframework:spring-context:$springVersion"
- compile "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion"
- compile "com.graphql-java:graphql-java:$graphqlJavaVersion"
+apply plugin: 'java-library'
- testCompile("org.assertj:assertj-core:$assertJVersion")
- testCompile group: 'junit', name: 'junit', version: '4.12'
- testCompile "org.springframework:spring-test:$springVersion"
- testCompile group: 'javax.servlet', name: 'javax.servlet-api', version: '4.0.1'
- testCompile group: 'com.jayway.jsonpath', name: 'json-path', version: '2.4.0'
- testCompile "org.mockito:mockito-core:2.+"
+dependencies {
+ implementation "org.springframework:spring-webmvc:$springVersion"
+ implementation "org.springframework:spring-context:$springVersion"
+ implementation "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion"
+ api "com.graphql-java:graphql-java:$graphqlJavaVersion"
+ implementation group: 'javax.servlet', name: 'javax.servlet-api', version: '4.0.1'
+
+ testImplementation("org.assertj:assertj-core:$assertJVersion")
+ testImplementation group: 'junit', name: 'junit', version: '4.12'
+ testImplementation "org.springframework:spring-test:$springVersion"
+ testImplementation group: 'com.jayway.jsonpath', name: 'json-path', version: '2.4.0'
+ testImplementation "org.mockito:mockito-core:2.+"
}
diff --git a/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/ExecutionInputCustomizer.java b/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/ExecutionInputCustomizer.java
deleted file mode 100644
index 6f326d0c..00000000
--- a/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/ExecutionInputCustomizer.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.springframework.graphql;
-
-import graphql.ExecutionInput;
-import graphql.PublicApi;
-import org.springframework.web.context.request.WebRequest;
-
-import java.util.concurrent.CompletableFuture;
-
-/**
- * Lets you customize the #ExecutionInput before the query is executed.
- * You can for example set a context object or define a root value.
- *
- * This is only used if you use the default {@link GraphQLInvocation}.
- */
-@PublicApi
-public interface ExecutionInputCustomizer {
-
- CompletableFuture customizeExecutionInput(ExecutionInput executionInput, WebRequest webRequest);
-
-}
diff --git a/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/ExecutionResultHandler.java b/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/ExecutionResultHandler.java
deleted file mode 100644
index 21d4d1e7..00000000
--- a/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/ExecutionResultHandler.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.springframework.graphql;
-
-import graphql.ExecutionResult;
-import graphql.PublicSpi;
-
-import java.util.concurrent.CompletableFuture;
-
-@PublicSpi
-public interface ExecutionResultHandler {
-
- Object handleExecutionResult(CompletableFuture executionResultCF);
-}
diff --git a/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/GraphQLInvocation.java b/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/GraphQLInvocation.java
deleted file mode 100644
index 3c033bba..00000000
--- a/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/GraphQLInvocation.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.springframework.graphql;
-
-import graphql.ExecutionResult;
-import graphql.PublicApi;
-import org.springframework.web.context.request.WebRequest;
-
-import java.util.concurrent.CompletableFuture;
-
-@PublicApi
-public interface GraphQLInvocation {
-
- CompletableFuture invoke(GraphQLInvocationData invocationData, WebRequest webRequest);
-
-}
diff --git a/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/GraphQLInvocationData.java b/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/GraphQLInvocationData.java
index bccdf911..42c3e53e 100644
--- a/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/GraphQLInvocationData.java
+++ b/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/GraphQLInvocationData.java
@@ -1,12 +1,10 @@
package org.springframework.graphql;
import graphql.Assert;
-import graphql.PublicApi;
import java.util.Collections;
import java.util.Map;
-@PublicApi
public class GraphQLInvocationData {
private final String query;
diff --git a/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/components/DefaultExecutionInputCustomizer.java b/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/components/DefaultExecutionInputCustomizer.java
deleted file mode 100644
index 3c85c15e..00000000
--- a/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/components/DefaultExecutionInputCustomizer.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.springframework.graphql.components;
-
-import graphql.ExecutionInput;
-import graphql.Internal;
-import org.springframework.graphql.ExecutionInputCustomizer;
-import org.springframework.stereotype.Component;
-import org.springframework.web.context.request.WebRequest;
-
-import java.util.concurrent.CompletableFuture;
-
-@Component
-@Internal
-public class DefaultExecutionInputCustomizer implements ExecutionInputCustomizer {
-
- @Override
- public CompletableFuture customizeExecutionInput(ExecutionInput executionInput, WebRequest webRequest) {
- return CompletableFuture.completedFuture(executionInput);
- }
-}
diff --git a/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/components/DefaultExecutionResultHandler.java b/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/components/DefaultExecutionResultHandler.java
deleted file mode 100644
index bf69c095..00000000
--- a/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/components/DefaultExecutionResultHandler.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.springframework.graphql.components;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import graphql.ExecutionResult;
-import graphql.Internal;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.graphql.ExecutionResultHandler;
-import org.springframework.stereotype.Component;
-
-import java.util.concurrent.CompletableFuture;
-
-@Component
-@Internal
-public class DefaultExecutionResultHandler implements ExecutionResultHandler {
-
- @Autowired
- ObjectMapper objectMapper;
-
- @Override
- public Object handleExecutionResult(CompletableFuture executionResultCF) {
- return executionResultCF.thenApply(ExecutionResult::toSpecification);
- }
-}
diff --git a/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/components/DefaultGraphQLInvocation.java b/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/components/DefaultGraphQLInvocation.java
deleted file mode 100644
index a56a23c9..00000000
--- a/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/components/DefaultGraphQLInvocation.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.springframework.graphql.components;
-
-import graphql.ExecutionInput;
-import graphql.ExecutionResult;
-import graphql.GraphQL;
-import graphql.Internal;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.graphql.ExecutionInputCustomizer;
-import org.springframework.graphql.GraphQLInvocation;
-import org.springframework.graphql.GraphQLInvocationData;
-import org.springframework.stereotype.Component;
-import org.springframework.web.context.request.WebRequest;
-
-import java.util.concurrent.CompletableFuture;
-
-@Component
-@Internal
-public class DefaultGraphQLInvocation implements GraphQLInvocation {
-
- @Autowired
- GraphQL graphQL;
-
- @Autowired
- ExecutionInputCustomizer executionInputCustomizer;
-
- @Override
- public CompletableFuture invoke(GraphQLInvocationData invocationData, WebRequest webRequest) {
- ExecutionInput executionInput = ExecutionInput.newExecutionInput()
- .query(invocationData.getQuery())
- .operationName(invocationData.getOperationName())
- .variables(invocationData.getVariables())
- .build();
- CompletableFuture customizedExecutionInput = executionInputCustomizer.customizeExecutionInput(executionInput, webRequest);
- return customizedExecutionInput.thenCompose(graphQL::executeAsync);
- }
-
-}
diff --git a/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/components/GraphQLController.java b/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/components/GraphQLController.java
index 1f24fc3a..914bea96 100644
--- a/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/components/GraphQLController.java
+++ b/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/components/GraphQLController.java
@@ -1,43 +1,49 @@
package org.springframework.graphql.components;
-import graphql.ExecutionResult;
-import graphql.Internal;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.graphql.ExecutionResultHandler;
-import org.springframework.graphql.GraphQLInvocation;
+import org.springframework.context.annotation.Bean;
import org.springframework.graphql.GraphQLInvocationData;
-import org.springframework.http.MediaType;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.context.request.WebRequest;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.function.RouterFunction;
+import org.springframework.web.servlet.function.ServerRequest;
+import org.springframework.web.servlet.function.ServerResponse;
-import java.util.concurrent.CompletableFuture;
+import java.io.IOException;
-@RestController
-@Internal
+import static org.springframework.web.servlet.function.RouterFunctions.route;
+
+@Component
public class GraphQLController {
@Autowired
- GraphQLInvocation graphQLInvocation;
+ GraphQLRequestHandler graphQLRequestHandler;
- @Autowired
- ExecutionResultHandler executionResultHandler;
+ @Bean
+ public RouterFunction routerFunction() {
+ RouterFunction route = route()
+ .POST("/graphql", this::graphqlPOST)
+ .build();
+ return route;
- @RequestMapping(value = "${graphql.url:graphql}",
- method = RequestMethod.POST,
- consumes = MediaType.APPLICATION_JSON_VALUE,
- produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
- public Object graphqlPOST(@RequestBody GraphQLRequestBody body,
- WebRequest webRequest) {
+ }
+
+ private ServerResponse graphqlPOST(ServerRequest serverRequest) {
+ GraphQLRequestBody body = null;
+ try {
+ body = serverRequest.body(GraphQLRequestBody.class);
+ } catch (javax.servlet.ServletException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
String query = body.getQuery();
if (query == null) {
query = "";
}
- CompletableFuture executionResult = graphQLInvocation.invoke(new GraphQLInvocationData(query, body.getOperationName(), body.getVariables()), webRequest);
- return executionResultHandler.handleExecutionResult(executionResult);
+ GraphQLInvocationData invocationData = new GraphQLInvocationData(query, body.getOperationName(), body.getVariables());
+ Object resultBody = graphQLRequestHandler.invoke(invocationData, serverRequest.headers());
+ return ServerResponse.ok().body(resultBody);
}
}
diff --git a/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/components/GraphQLRequestBody.java b/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/components/GraphQLRequestBody.java
index 10697e30..2cb1e6e3 100644
--- a/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/components/GraphQLRequestBody.java
+++ b/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/components/GraphQLRequestBody.java
@@ -1,10 +1,7 @@
package org.springframework.graphql.components;
-import graphql.Internal;
-
import java.util.Map;
-@Internal
public class GraphQLRequestBody {
private String query;
private String operationName;
diff --git a/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/components/GraphQLRequestHandler.java b/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/components/GraphQLRequestHandler.java
new file mode 100644
index 00000000..dd01bd50
--- /dev/null
+++ b/graphql-java-spring-webmvc/src/main/java/org/springframework/graphql/components/GraphQLRequestHandler.java
@@ -0,0 +1,55 @@
+package org.springframework.graphql.components;
+
+import graphql.ExecutionInput;
+import graphql.ExecutionResult;
+import graphql.GraphQL;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.graphql.GraphQLInvocationData;
+import org.springframework.stereotype.Component;
+import org.springframework.util.Assert;
+import org.springframework.web.servlet.function.ServerRequest;
+
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+
+@Component
+public class GraphQLRequestHandler {
+
+ @Autowired
+ private GraphQL graphQL;
+
+
+ public Object invoke(GraphQLInvocationData invocationData,
+ ServerRequest.Headers headers) {
+ Assert.notNull(graphQL, "graphQL is not set");
+ ExecutionInput executionInput = ExecutionInput.newExecutionInput()
+ .query(invocationData.getQuery())
+ .operationName(invocationData.getOperationName())
+ .variables(invocationData.getVariables())
+ .build();
+ customizeExecutionInput(executionInput, headers);
+ CompletableFuture customizedExecutionInput = customizeExecutionInput(executionInput, headers);
+ CompletableFuture executionResultCompletableFuture = customizedExecutionInput.thenCompose(graphQL::executeAsync);
+ return handleExecutionResult(executionResultCompletableFuture);
+ }
+
+ protected CompletableFuture customizeExecutionInput(ExecutionInput executionInput,
+ ServerRequest.Headers headers) {
+ return CompletableFuture.completedFuture(executionInput);
+ }
+
+ protected Object handleExecutionResult(CompletableFuture executionResultCF) {
+ if (executionResultCF.isDone()) {
+ return toSpecification(executionResultCF);
+ }
+ return executionResultCF.thenApply(ExecutionResult::toSpecification);
+ }
+
+ private Map toSpecification(CompletableFuture executionResultCF) {
+ try {
+ return executionResultCF.get().toSpecification();
+ } catch (Exception e) {
+ throw new RuntimeException("Should not happen", e);
+ }
+ }
+}