Expose ExecutionInput in WebOutput
WebOutput now exposes the ExecutionInput prepared for the request and no longer provides access to the WebInput which is already available to a WebInterceptor. Closes gh-229
This commit is contained in:
@@ -24,6 +24,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import graphql.ExecutionInput;
|
||||
import graphql.ExecutionResult;
|
||||
import graphql.ExecutionResultImpl;
|
||||
import graphql.GraphQLError;
|
||||
@@ -352,9 +353,10 @@ public class GraphQlTesterTests {
|
||||
if (!CollectionUtils.isEmpty(errors)) {
|
||||
builder.addErrors(errors);
|
||||
}
|
||||
RequestInput input = new RequestInput("{}", null, null, null, "1");
|
||||
ExecutionInput executionInput = ExecutionInput.newExecutionInput("{}").build();
|
||||
ExecutionResult result = builder.build();
|
||||
given(this.service.execute(this.inputCaptor.capture())).willReturn(Mono.just(new RequestOutput(input, result)));
|
||||
given(this.service.execute(this.inputCaptor.capture()))
|
||||
.willReturn(Mono.just(new RequestOutput(executionInput, result)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.util.stream.Stream;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import graphql.ExecutionInput;
|
||||
import graphql.ExecutionResult;
|
||||
import graphql.ExecutionResultImpl;
|
||||
import graphql.GraphQLError;
|
||||
@@ -38,6 +39,7 @@ import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.graphql.RequestOutput;
|
||||
import org.springframework.graphql.web.WebGraphQlHandler;
|
||||
import org.springframework.graphql.web.WebInput;
|
||||
import org.springframework.graphql.web.WebOutput;
|
||||
@@ -271,8 +273,9 @@ public class WebGraphQlTesterTests {
|
||||
if (!CollectionUtils.isEmpty(errors)) {
|
||||
builder.addErrors(errors);
|
||||
}
|
||||
ExecutionInput executionInput = ExecutionInput.newExecutionInput("{}").build();
|
||||
ExecutionResult result = builder.build();
|
||||
WebOutput output = new WebOutput(mock(WebInput.class), result);
|
||||
WebOutput output = new WebOutput(new RequestOutput(executionInput, result));
|
||||
given(this.handler.handleRequest(this.bodyCaptor.capture())).willReturn(Mono.just(output));
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,7 @@ package org.springframework.graphql;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* Strategy to perform GraphQL request execution with input for and output from the
|
||||
* invocation of {@link graphql.GraphQL}.
|
||||
* Strategy to perform a GraphQL request.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
@@ -29,8 +28,8 @@ public interface GraphQlService {
|
||||
|
||||
/**
|
||||
* Perform the operation and return the result.
|
||||
* @param input container for the GraphQL request input
|
||||
* @return the execution result
|
||||
* @param input container for GraphQL request input
|
||||
* @return the result from execution
|
||||
*/
|
||||
Mono<RequestOutput> execute(RequestInput input);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.graphql;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import graphql.ExecutionInput;
|
||||
import graphql.ExecutionResult;
|
||||
import graphql.GraphQLError;
|
||||
|
||||
@@ -25,36 +26,38 @@ import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* An {@link ExecutionResult} that also holds the {@link RequestInput}.
|
||||
* Wraps an {@link ExecutionResult} and also exposes the {@link ExecutionInput}
|
||||
* prepared for the request.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class RequestOutput implements ExecutionResult {
|
||||
|
||||
private final RequestInput requestInput;
|
||||
private final ExecutionInput executionInput;
|
||||
|
||||
private final ExecutionResult executionResult;
|
||||
|
||||
|
||||
/**
|
||||
* Create an instance that wraps the given {@link ExecutionResult}.
|
||||
* @param requestInput the container for the GraphQL input
|
||||
* @param executionResult the result of performing a graphql query
|
||||
* Create an instance.
|
||||
* @param executionInput the input prepared for the request
|
||||
* @param executionResult the result from performing the request
|
||||
*/
|
||||
public RequestOutput(RequestInput requestInput, ExecutionResult executionResult) {
|
||||
Assert.notNull(requestInput, "RequestInput is required.");
|
||||
public RequestOutput(ExecutionInput executionInput, ExecutionResult executionResult) {
|
||||
Assert.notNull(executionInput, "ExecutionInput is required.");
|
||||
Assert.notNull(executionResult, "ExecutionResult is required.");
|
||||
this.requestInput = requestInput;
|
||||
this.executionInput = executionInput;
|
||||
this.executionResult = executionResult;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the associated {@link RequestInput} used for the execution.
|
||||
* @return the associated WebInput
|
||||
* Return the {@link ExecutionInput} that was prepared from the
|
||||
* {@link RequestInput} and passed to {@link graphql.GraphQL}.
|
||||
*/
|
||||
public RequestInput getRequestInput() {
|
||||
return this.requestInput;
|
||||
public ExecutionInput getExecutionInput() {
|
||||
return this.executionInput;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -63,9 +63,9 @@ public class ExecutionGraphQlService implements GraphQlService {
|
||||
return Mono.deferContextual((contextView) -> {
|
||||
ExecutionInput executionInput = requestInput.toExecutionInput();
|
||||
ReactorContextManager.setReactorContext(contextView, executionInput);
|
||||
executionInput = registerDataLoaders(executionInput);
|
||||
return Mono.fromFuture(this.graphQlSource.graphQl().executeAsync(executionInput))
|
||||
.map(result -> new RequestOutput(requestInput, result));
|
||||
ExecutionInput updatedExecutionInput = registerDataLoaders(executionInput);
|
||||
return Mono.fromFuture(this.graphQlSource.graphQl().executeAsync(updatedExecutionInput))
|
||||
.map(result -> new RequestOutput(updatedExecutionInput, result));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -119,12 +119,11 @@ class DefaultWebGraphQlHandlerBuilder implements WebGraphQlHandler.Builder {
|
||||
|
||||
private WebInterceptorChain initWebInterceptorChain(List<WebInterceptor> interceptors) {
|
||||
|
||||
WebInterceptorChain endOfChain =
|
||||
webInput -> service.execute(webInput).map((result) -> new WebOutput(webInput, result));
|
||||
WebInterceptorChain endOfChain = webInput -> this.service.execute(webInput).map(WebOutput::new);
|
||||
|
||||
return interceptors.stream()
|
||||
.reduce(WebInterceptor::andThen)
|
||||
.map((interceptor) -> (WebInterceptorChain) (input) -> interceptor.intercept(input, endOfChain))
|
||||
.map(interceptor -> (WebInterceptorChain) (input) -> interceptor.intercept(input, endOfChain))
|
||||
.orElse(endOfChain);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import graphql.ExecutionInput;
|
||||
import graphql.ExecutionResult;
|
||||
import graphql.ExecutionResultImpl;
|
||||
import graphql.GraphQLError;
|
||||
@@ -45,24 +46,21 @@ public class WebOutput extends RequestOutput {
|
||||
|
||||
/**
|
||||
* Create an instance that wraps the given {@link ExecutionResult}.
|
||||
* @param input the container for the GraphQL input
|
||||
* @param executionResult the result of performing a graphql query
|
||||
* @param requestOutput the output from an executed request
|
||||
*/
|
||||
public WebOutput(WebInput input, ExecutionResult executionResult) {
|
||||
this(input, executionResult, null);
|
||||
public WebOutput(RequestOutput requestOutput) {
|
||||
this(requestOutput.getExecutionInput(), requestOutput, null);
|
||||
}
|
||||
|
||||
private WebOutput(WebInput input, ExecutionResult executionResult, @Nullable HttpHeaders responseHeaders) {
|
||||
super(input, executionResult);
|
||||
private WebOutput(
|
||||
ExecutionInput executionInput, ExecutionResult executionResult,
|
||||
@Nullable HttpHeaders responseHeaders) {
|
||||
|
||||
super(executionInput, executionResult);
|
||||
this.responseHeaders = responseHeaders;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public WebInput getRequestInput() {
|
||||
return (WebInput) super.getRequestInput();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a read-only view of any custom headers to be added to the HTTP response, or
|
||||
* {@code null} until {@link #transform(Consumer)} is used to add such headers.
|
||||
@@ -93,7 +91,7 @@ public class WebOutput extends RequestOutput {
|
||||
*/
|
||||
public static final class Builder {
|
||||
|
||||
private final WebInput input;
|
||||
private final ExecutionInput executionInput;
|
||||
|
||||
@Nullable
|
||||
private Object data;
|
||||
@@ -107,7 +105,7 @@ public class WebOutput extends RequestOutput {
|
||||
private HttpHeaders headers;
|
||||
|
||||
private Builder(WebOutput output) {
|
||||
this.input = output.getRequestInput();
|
||||
this.executionInput = output.getExecutionInput();
|
||||
this.data = output.getData();
|
||||
this.errors = output.getErrors();
|
||||
this.extensions = output.getExtensions();
|
||||
@@ -187,7 +185,7 @@ public class WebOutput extends RequestOutput {
|
||||
|
||||
public WebOutput build() {
|
||||
ExecutionResult result = new ExecutionResultImpl(this.data, this.errors, this.extensions);
|
||||
return new WebOutput(this.input, result, this.headers);
|
||||
return new WebOutput(this.executionInput, result, this.headers);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.Collections;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Function;
|
||||
|
||||
import graphql.ExecutionInput;
|
||||
import graphql.ExecutionResultImpl;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
@@ -92,7 +93,9 @@ public class WebInterceptorTests {
|
||||
}
|
||||
|
||||
private Mono<RequestOutput> emptyExecutionResult(RequestInput input) {
|
||||
return Mono.just(new RequestOutput(input, ExecutionResultImpl.newExecutionResult().build()));
|
||||
return Mono.just(new RequestOutput(
|
||||
ExecutionInput.newExecutionInput("{}").build(),
|
||||
ExecutionResultImpl.newExecutionResult().build()));
|
||||
}
|
||||
|
||||
private static class OrderInterceptor implements WebInterceptor {
|
||||
|
||||
Reference in New Issue
Block a user