|
9 | 9 | import graphql.kickstart.execution.input.GraphQLInvocationInput;
|
10 | 10 | import graphql.kickstart.execution.input.GraphQLSingleInvocationInput;
|
11 | 11 | import java.io.IOException;
|
| 12 | +import java.io.UncheckedIOException; |
| 13 | +import java.util.concurrent.CompletableFuture; |
| 14 | +import javax.servlet.AsyncContext; |
12 | 15 | import javax.servlet.http.HttpServletRequest;
|
13 | 16 | import javax.servlet.http.HttpServletResponse;
|
14 | 17 | import lombok.extern.slf4j.Slf4j;
|
@@ -48,37 +51,60 @@ public void handle(HttpServletRequest request, HttpServletResponse response) thr
|
48 | 51 |
|
49 | 52 | private void execute(GraphQLInvocationInput invocationInput, HttpServletRequest request,
|
50 | 53 | HttpServletResponse response) {
|
51 |
| - try { |
52 |
| - GraphQLQueryResult queryResult = invoke(invocationInput, request, response); |
| 54 | + if (request.isAsyncSupported()) { |
| 55 | + AsyncContext asyncContext = request.startAsync(request, response); |
| 56 | + asyncContext.setTimeout(configuration.getAsyncTimeout()); |
| 57 | + invoke(invocationInput, request, response) |
| 58 | + .thenAccept(result -> writeResultResponse(result, request, response)) |
| 59 | + .exceptionally(t -> writeErrorResponse(t, response)) |
| 60 | + .thenAccept(aVoid -> asyncContext.complete()); |
| 61 | + } else { |
| 62 | + try { |
| 63 | + GraphQLQueryResult result = invoke(invocationInput, request, response).join(); |
| 64 | + writeResultResponse(result, request, response); |
| 65 | + } catch (Throwable t) { |
| 66 | + writeErrorResponse(t, response); |
| 67 | + } |
| 68 | + } |
| 69 | + } |
53 | 70 |
|
54 |
| - QueryResponseWriter queryResponseWriter = QueryResponseWriter.createWriter(queryResult, configuration.getObjectMapper(), |
55 |
| - configuration.getSubscriptionTimeout()); |
| 71 | + private void writeResultResponse(GraphQLQueryResult queryResult, HttpServletRequest request, |
| 72 | + HttpServletResponse response) { |
| 73 | + QueryResponseWriter queryResponseWriter = QueryResponseWriter.createWriter(queryResult, configuration.getObjectMapper(), |
| 74 | + configuration.getSubscriptionTimeout()); |
| 75 | + try { |
56 | 76 | queryResponseWriter.write(request, response);
|
57 |
| - } catch (Throwable t) { |
58 |
| - response.setStatus(STATUS_BAD_REQUEST); |
59 |
| - log.info("Bad GET request: path was not \"/schema.json\" or no query variable named \"query\" given"); |
60 |
| - log.debug("Possibly due to exception: ", t); |
| 77 | + } catch (IOException e) { |
| 78 | + // will be processed by the exceptionally() call below |
| 79 | + throw new UncheckedIOException(e); |
61 | 80 | }
|
62 | 81 | }
|
63 | 82 |
|
64 |
| - private GraphQLQueryResult invoke(GraphQLInvocationInput invocationInput, HttpServletRequest request, |
| 83 | + private Void writeErrorResponse(Throwable t, HttpServletResponse response) { |
| 84 | + response.setStatus(STATUS_BAD_REQUEST); |
| 85 | + log.info("Bad GET request: path was not \"/schema.json\" or no query variable named \"query\" given"); |
| 86 | + log.debug("Possibly due to exception: ", t); |
| 87 | + return null; |
| 88 | + } |
| 89 | + |
| 90 | + private CompletableFuture<GraphQLQueryResult> invoke(GraphQLInvocationInput invocationInput, HttpServletRequest request, |
65 | 91 | HttpServletResponse response) {
|
66 | 92 | if (invocationInput instanceof GraphQLSingleInvocationInput) {
|
67 |
| - return graphQLInvoker.query(invocationInput); |
| 93 | + return graphQLInvoker.queryAsync(invocationInput); |
68 | 94 | }
|
69 | 95 | return invokeBatched((GraphQLBatchedInvocationInput) invocationInput, request, response);
|
70 | 96 | }
|
71 | 97 |
|
72 |
| - private GraphQLQueryResult invokeBatched(GraphQLBatchedInvocationInput batchedInvocationInput, |
| 98 | + private CompletableFuture<GraphQLQueryResult> invokeBatched(GraphQLBatchedInvocationInput batchedInvocationInput, |
73 | 99 | HttpServletRequest request,
|
74 | 100 | HttpServletResponse response) {
|
75 | 101 | BatchInputPreProcessor preprocessor = configuration.getBatchInputPreProcessor();
|
76 | 102 | BatchInputPreProcessResult result = preprocessor.preProcessBatch(batchedInvocationInput, request, response);
|
77 | 103 | if (result.isExecutable()) {
|
78 |
| - return graphQLInvoker.query(result.getBatchedInvocationInput()); |
| 104 | + return graphQLInvoker.queryAsync(result.getBatchedInvocationInput()); |
79 | 105 | }
|
80 | 106 |
|
81 |
| - return GraphQLQueryResult.createError(result.getStatusCode(), result.getStatusMessage()); |
| 107 | + return CompletableFuture.completedFuture(GraphQLQueryResult.createError(result.getStatusCode(), result.getStatusMessage())); |
82 | 108 | }
|
83 | 109 |
|
84 | 110 | }
|
0 commit comments