Rename Web[Input|Output] to WebGraphQl[Request|Response]
See gh-332
This commit is contained in:
@@ -130,12 +130,12 @@ transformation of the `graphql.ExecutionInput`:
|
||||
class MyInterceptor implements WebInterceptor {
|
||||
|
||||
@Override
|
||||
public Mono<WebOutput> intercept(WebInput webInput, WebInterceptorChain chain) {
|
||||
webInput.configureExecutionInput((executionInput, builder) -> {
|
||||
public Mono<WebGraphQlResponse> intercept(WebGraphQlRequest request, WebInterceptorChain chain) {
|
||||
request.configureExecutionInput((executionInput, builder) -> {
|
||||
Map<String, Object> map = ... ;
|
||||
return builder.extensions(map).build();
|
||||
});
|
||||
return chain.next(webInput);
|
||||
return chain.next(request);
|
||||
}
|
||||
}
|
||||
----
|
||||
@@ -148,12 +148,12 @@ the `graphql.ExecutionResult`:
|
||||
class MyInterceptor implements WebInterceptor {
|
||||
|
||||
@Override
|
||||
public Mono<WebOutput> intercept(WebInput webInput, WebInterceptorChain chain) {
|
||||
return chain.next(webInput)
|
||||
.map(webOutput -> {
|
||||
Object data = webOutput.getData();
|
||||
public Mono<WebGraphQlResponse> intercept(WebGraphQlRequest request, WebInterceptorChain chain) {
|
||||
return chain.next(request)
|
||||
.map(response -> {
|
||||
Object data = response.getData();
|
||||
Object updatedData = ... ;
|
||||
return webOutput.transform(builder -> builder.data(updatedData));
|
||||
return response.transform(builder -> builder.data(updatedData));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,15 +18,14 @@ package org.springframework.graphql.test.tester;
|
||||
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.graphql.ExecutionGraphQlRequest;
|
||||
import org.springframework.graphql.ExecutionGraphQlResponse;
|
||||
import org.springframework.graphql.GraphQlRequest;
|
||||
import org.springframework.graphql.web.WebGraphQlHandler;
|
||||
import org.springframework.graphql.web.WebInput;
|
||||
import org.springframework.graphql.web.WebOutput;
|
||||
import org.springframework.graphql.web.WebGraphQlRequest;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.codec.CodecConfigurer;
|
||||
import org.springframework.lang.Nullable;
|
||||
@@ -77,9 +76,15 @@ final class WebGraphQlHandlerTransport extends AbstractDirectTransport {
|
||||
|
||||
|
||||
@Override
|
||||
protected Mono<ExecutionGraphQlResponse> executeInternal(ExecutionGraphQlRequest request) {
|
||||
WebInput input = new WebInput(this.url, this.headers, request.toMap(), idGenerator.generateId().toString(), null);
|
||||
return this.graphQlHandler.handleRequest(input).cast(ExecutionGraphQlResponse.class);
|
||||
protected Mono<ExecutionGraphQlResponse> executeInternal(ExecutionGraphQlRequest executionRequest) {
|
||||
|
||||
String id = idGenerator.generateId().toString();
|
||||
Map<String, Object> body = executionRequest.toMap();
|
||||
|
||||
WebGraphQlRequest webExecutionRequest =
|
||||
new WebGraphQlRequest(this.url, this.headers, body, id, null);
|
||||
|
||||
return this.graphQlHandler.handleRequest(webExecutionRequest).cast(ExecutionGraphQlResponse.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,10 +37,10 @@ import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.graphql.ExecutionGraphQlResponse;
|
||||
import org.springframework.graphql.support.DefaultExecutionGraphQlResponse;
|
||||
import org.springframework.graphql.support.DocumentSource;
|
||||
import org.springframework.graphql.web.WebGraphQlRequest;
|
||||
import org.springframework.graphql.web.TestWebSocketClient;
|
||||
import org.springframework.graphql.web.TestWebSocketConnection;
|
||||
import org.springframework.graphql.web.WebGraphQlHandler;
|
||||
import org.springframework.graphql.web.WebInput;
|
||||
import org.springframework.graphql.web.WebInterceptor;
|
||||
import org.springframework.graphql.web.webflux.GraphQlHttpHandler;
|
||||
import org.springframework.graphql.web.webflux.GraphQlWebSocketHandler;
|
||||
@@ -60,8 +60,8 @@ import static org.springframework.web.reactive.function.server.RouterFunctions.r
|
||||
|
||||
/**
|
||||
* Tests for the builders of Web {@code GraphQlTester} extensions, using a
|
||||
* {@link WebInterceptor} to capture the WebInput on the server side, and
|
||||
* optionally returning a mock response, or an empty response.
|
||||
* {@link WebInterceptor} to capture the WebGraphQlRequest on the server side,
|
||||
* and optionally returning a mock response, or an empty response.
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@link HttpGraphQlTester} via {@link WebTestClient} to {@link GraphQlHttpHandler}
|
||||
@@ -95,24 +95,24 @@ public class WebGraphQlTesterBuilderTests {
|
||||
WebGraphQlTester tester = builder.build();
|
||||
tester.document(DOCUMENT).execute();
|
||||
|
||||
WebInput input = builderSetup.getWebInput();
|
||||
assertThat(input.getUri().toString()).isEqualTo(url);
|
||||
assertThat(input.getHeaders().get("h")).containsExactly("one");
|
||||
WebGraphQlRequest request = builderSetup.getWebGraphQlRequest();
|
||||
assertThat(request.getUri().toString()).isEqualTo(url);
|
||||
assertThat(request.getHeaders().get("h")).containsExactly("one");
|
||||
|
||||
// Mutate to add header value
|
||||
builder = tester.mutate().headers(headers -> headers.add("h", "two"));
|
||||
tester = builder.build();
|
||||
tester.document(DOCUMENT).execute();
|
||||
assertThat(builderSetup.getWebInput().getHeaders().get("h")).containsExactly("one", "two");
|
||||
assertThat(builderSetup.getWebGraphQlRequest().getHeaders().get("h")).containsExactly("one", "two");
|
||||
|
||||
// Mutate to replace header
|
||||
builder = tester.mutate().header("h", "three", "four");
|
||||
tester = builder.build();
|
||||
tester.document(DOCUMENT).execute();
|
||||
|
||||
input = builderSetup.getWebInput();
|
||||
assertThat(input.getUri().toString()).isEqualTo(url);
|
||||
assertThat(input.getHeaders().get("h")).containsExactly("three", "four");
|
||||
request = builderSetup.getWebGraphQlRequest();
|
||||
assertThat(request.getUri().toString()).isEqualTo(url);
|
||||
assertThat(request.getHeaders().get("h")).containsExactly("three", "four");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -125,7 +125,7 @@ public class WebGraphQlTesterBuilderTests {
|
||||
|
||||
HttpGraphQlTester tester = builder.build();
|
||||
tester.document(DOCUMENT).execute();
|
||||
assertThat(testerSetup.getWebInput().getHeaders().get("h")).containsExactly("one");
|
||||
assertThat(testerSetup.getWebGraphQlRequest().getHeaders().get("h")).containsExactly("one");
|
||||
|
||||
// Mutate to add header value
|
||||
HttpGraphQlTester.Builder<?> builder2 = tester.mutate()
|
||||
@@ -133,7 +133,7 @@ public class WebGraphQlTesterBuilderTests {
|
||||
|
||||
tester = builder2.build();
|
||||
tester.document(DOCUMENT).execute();
|
||||
assertThat(testerSetup.getWebInput().getHeaders().get("h")).containsExactly("one", "two");
|
||||
assertThat(testerSetup.getWebGraphQlRequest().getHeaders().get("h")).containsExactly("one", "two");
|
||||
|
||||
// Mutate to replace header
|
||||
HttpGraphQlTester.Builder<?> builder3 = tester.mutate()
|
||||
@@ -141,7 +141,7 @@ public class WebGraphQlTesterBuilderTests {
|
||||
|
||||
tester = builder3.build();
|
||||
tester.document(DOCUMENT).execute();
|
||||
assertThat(testerSetup.getWebInput().getHeaders().get("h")).containsExactly("three");
|
||||
assertThat(testerSetup.getWebGraphQlRequest().getHeaders().get("h")).containsExactly("three");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@@ -156,14 +156,14 @@ public class WebGraphQlTesterBuilderTests {
|
||||
WebGraphQlTester tester = builder.build();
|
||||
tester.documentName("name").execute();
|
||||
|
||||
WebInput input = builderSetup.getWebInput();
|
||||
WebGraphQlRequest input = builderSetup.getWebGraphQlRequest();
|
||||
assertThat(input.getDocument()).isEqualTo(DOCUMENT);
|
||||
|
||||
// Mutate
|
||||
tester = tester.mutate().build();
|
||||
tester.documentName("name").execute();
|
||||
|
||||
input = builderSetup.getWebInput();
|
||||
input = builderSetup.getWebGraphQlRequest();
|
||||
assertThat(input.getDocument()).isEqualTo(DOCUMENT);
|
||||
}
|
||||
|
||||
@@ -202,14 +202,14 @@ public class WebGraphQlTesterBuilderTests {
|
||||
|
||||
void setMockResponse(String document, ExecutionResult result);
|
||||
|
||||
WebInput getWebInput();
|
||||
WebGraphQlRequest getWebGraphQlRequest();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static class WebBuilderSetup implements TesterBuilderSetup {
|
||||
|
||||
private WebInput webInput;
|
||||
private WebGraphQlRequest request;
|
||||
|
||||
private final Map<String, ExecutionGraphQlResponse> responses = new HashMap<>();
|
||||
|
||||
@@ -235,8 +235,8 @@ public class WebGraphQlTesterBuilderTests {
|
||||
return Mono.just(response);
|
||||
})
|
||||
.interceptor((input, chain) -> {
|
||||
this.webInput = input;
|
||||
return chain.next(webInput);
|
||||
this.request = input;
|
||||
return chain.next(request);
|
||||
})
|
||||
.build();
|
||||
}
|
||||
@@ -248,8 +248,8 @@ public class WebGraphQlTesterBuilderTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebInput getWebInput() {
|
||||
return this.webInput;
|
||||
public WebGraphQlRequest getWebGraphQlRequest() {
|
||||
return this.request;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -82,8 +82,8 @@ public interface ExecutionGraphQlRequest extends GraphQlRequest {
|
||||
/**
|
||||
* Provide a {@code BiFunction} to help initialize the {@link ExecutionInput}
|
||||
* passed to {@link graphql.GraphQL}. The {@code ExecutionInput} is first
|
||||
* pre-populated with values from "this" {@code RequestInput}, and is then
|
||||
* customized with the functions provided here.
|
||||
* pre-populated with values from "this" {@code ExecutionGraphQlRequest}, and
|
||||
* is then customized with the functions provided here.
|
||||
* @param configurer a {@code BiFunction} that accepts the
|
||||
* {@code ExecutionInput} initialized so far, and a builder to customize it.
|
||||
*/
|
||||
@@ -92,8 +92,8 @@ public interface ExecutionGraphQlRequest extends GraphQlRequest {
|
||||
/**
|
||||
* Create the {@link ExecutionInput} to pass to {@link graphql.GraphQL}.
|
||||
* passed to {@link graphql.GraphQL}. The {@code ExecutionInput} is populated
|
||||
* with values from "this" {@code RequestInput}, and then customized with
|
||||
* functions provided via {@link #configureExecutionInput(BiFunction)}.
|
||||
* with values from "this" {@code ExecutionGraphQlRequest}, and then customized
|
||||
* with functions provided via {@link #configureExecutionInput(BiFunction)}.
|
||||
* @return the resulting {@code ExecutionInput}
|
||||
*/
|
||||
ExecutionInput toExecutionInput();
|
||||
|
||||
@@ -341,8 +341,8 @@ public abstract class QuerydslDataFetcher<T> {
|
||||
* {@link #autoRegistrationConfigurer(List, List) auto-registration}.
|
||||
* For manual registration, you will need to use this method to apply it.
|
||||
*
|
||||
* @param customizer to customize GraphQL request input to Querydsl
|
||||
* Predicate binding with
|
||||
* @param customizer to customize the binding of the GraphQL request to
|
||||
* Querydsl Predicate
|
||||
* @return a new {@link Builder} instance with all previously configured
|
||||
* options and {@code QuerydslBinderCustomizer} applied
|
||||
*/
|
||||
|
||||
@@ -35,8 +35,8 @@ import org.springframework.util.Assert;
|
||||
* or WebSocket handler) assigned {@link #getId() id} and {@link #getLocale()
|
||||
* locale} in the addition to the {@code GraphQlRequest} inputs.
|
||||
*
|
||||
* <p>{@code RequestInput} supports the initialization of {@link ExecutionInput}
|
||||
* that is passed to {@link graphql.GraphQL}. You can customize that via
|
||||
* <p>Supports the initialization of {@link ExecutionInput} that is passed to
|
||||
* {@link graphql.GraphQL}. You can customize that via
|
||||
* {@link #configureExecutionInput(BiFunction)}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
|
||||
@@ -89,18 +89,18 @@ class DefaultWebGraphQlHandlerBuilder implements WebGraphQlHandler.Builder {
|
||||
public WebGraphQlHandler build() {
|
||||
|
||||
WebInterceptorChain endOfChain =
|
||||
webInput -> this.service.execute(webInput).map(WebOutput::new);
|
||||
request -> this.service.execute(request).map(WebGraphQlResponse::new);
|
||||
|
||||
WebInterceptorChain chain = this.interceptors.stream()
|
||||
.reduce(WebInterceptor::andThen)
|
||||
.map(interceptor -> (WebInterceptorChain) (input) -> interceptor.intercept(input, endOfChain))
|
||||
.map(interceptor -> (WebInterceptorChain) (request) -> interceptor.intercept(request, endOfChain))
|
||||
.orElse(endOfChain);
|
||||
|
||||
return new WebGraphQlHandler() {
|
||||
|
||||
@Override
|
||||
public Mono<WebOutput> handleRequest(WebInput input) {
|
||||
return chain.next(input)
|
||||
public Mono<WebGraphQlResponse> handleRequest(WebGraphQlRequest request) {
|
||||
return chain.next(request)
|
||||
.contextWrite(context -> {
|
||||
if (!CollectionUtils.isEmpty(accessors)) {
|
||||
ThreadLocalAccessor accessor = ThreadLocalAccessor.composite(accessors);
|
||||
|
||||
@@ -35,11 +35,11 @@ public interface WebGraphQlHandler {
|
||||
|
||||
|
||||
/**
|
||||
* Execute the given request and return the resulting output.
|
||||
* @param input the GraphQL request input container
|
||||
* @return the result from execution
|
||||
* Execute the given request and return the response.
|
||||
* @param request the request to execute
|
||||
* @return the response
|
||||
*/
|
||||
Mono<WebOutput> handleRequest(WebInput input);
|
||||
Mono<WebGraphQlResponse> handleRequest(WebGraphQlRequest request);
|
||||
|
||||
/**
|
||||
* Return the single interceptor of type {@link WebSocketInterceptor} among
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.net.URI;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.graphql.ExecutionGraphQlRequest;
|
||||
import org.springframework.graphql.support.DefaultExecutionGraphQlRequest;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.lang.Nullable;
|
||||
@@ -30,33 +31,38 @@ import org.springframework.web.util.UriComponents;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
/**
|
||||
* Container for the input of a GraphQL request over HTTP or WebSocket, including
|
||||
* the URL and HTTP headers, along with the query, operation name, and variables
|
||||
* from the body of the request. For WebSocket, the URL and HTTP headers are
|
||||
* those of the WebSocket handshake request.
|
||||
* {@link org.springframework.graphql.GraphQlRequest} implementation for server
|
||||
* handling over HTTP or WebSocket. Provides access to the URL and headers of
|
||||
* the underlying request. For WebSocket, these are the URL and headers of the
|
||||
* HTTP handshake request.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class WebInput extends DefaultExecutionGraphQlRequest {
|
||||
public class WebGraphQlRequest extends DefaultExecutionGraphQlRequest implements ExecutionGraphQlRequest {
|
||||
|
||||
private final UriComponents uri;
|
||||
|
||||
private final HttpHeaders headers;
|
||||
|
||||
|
||||
/**
|
||||
* Create an instance.
|
||||
* @param uri the URL for the HTTP request or WebSocket handshake
|
||||
* @param headers the HTTP request headers
|
||||
* @param body the deserialized content of the GraphQL request
|
||||
* @param id an identifier for the GraphQL request, e.g. a subscription id for
|
||||
* correlating request and response messages, or it could be an id associated with the
|
||||
* correlating request and response messages, or it could be an id associated with the
|
||||
* @param locale the locale from the HTTP request, if any
|
||||
*/
|
||||
public WebInput(URI uri, HttpHeaders headers, Map<String, Object> body, String id, @Nullable Locale locale) {
|
||||
public WebGraphQlRequest(
|
||||
URI uri, HttpHeaders headers, Map<String, Object> body, String id, @Nullable Locale locale) {
|
||||
|
||||
super(getKey("query", body), getKey("operationName", body), getKey("variables", body), id, locale);
|
||||
|
||||
Assert.notNull(uri, "URI is required'");
|
||||
Assert.notNull(headers, "HttpHeaders is required'");
|
||||
|
||||
this.uri = UriComponentsBuilder.fromUri(uri).build(true);
|
||||
this.headers = headers;
|
||||
}
|
||||
@@ -64,7 +70,7 @@ public class WebInput extends DefaultExecutionGraphQlRequest {
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> T getKey(String key, Map<String, Object> body) {
|
||||
if (key.equals("query") && !StringUtils.hasText((String) body.get(key))) {
|
||||
throw new ServerWebInputException("No \"query\" in the request input");
|
||||
throw new ServerWebInputException("No \"query\" in the request document");
|
||||
}
|
||||
return (T) body.get(key);
|
||||
}
|
||||
@@ -30,14 +30,13 @@ import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Decorate an {@link ExecutionResult}, provide a way to {@link #transform(Consumer)
|
||||
* transform} it, and collect input for custom HTTP response headers for GraphQL over HTTP
|
||||
* requests.
|
||||
* {@link org.springframework.graphql.GraphQlResponse} implementation for server
|
||||
* handling over HTTP or over WebSocket.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class WebOutput extends DefaultExecutionGraphQlResponse {
|
||||
public class WebGraphQlResponse extends DefaultExecutionGraphQlResponse {
|
||||
|
||||
private final HttpHeaders responseHeaders;
|
||||
|
||||
@@ -46,12 +45,12 @@ public class WebOutput extends DefaultExecutionGraphQlResponse {
|
||||
* Create an instance that wraps the given {@link ExecutionGraphQlResponse}.
|
||||
* @param response the response to wrap
|
||||
*/
|
||||
public WebOutput(ExecutionGraphQlResponse response) {
|
||||
public WebGraphQlResponse(ExecutionGraphQlResponse response) {
|
||||
super(response);
|
||||
this.responseHeaders = new HttpHeaders();
|
||||
}
|
||||
|
||||
private WebOutput(WebOutput original, ExecutionResult executionResult) {
|
||||
private WebGraphQlResponse(WebGraphQlResponse original, ExecutionResult executionResult) {
|
||||
super(original.getExecutionInput(), executionResult);
|
||||
this.responseHeaders = original.getResponseHeaders();
|
||||
}
|
||||
@@ -69,12 +68,12 @@ public class WebOutput extends DefaultExecutionGraphQlResponse {
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform this {@code WebOutput} instance through a {@link Builder} and return a
|
||||
* new instance with the modified values.
|
||||
* @param consumer teh callback that will transform the WebOutput
|
||||
* @return the transformed WebOutput
|
||||
* Transform the underlying {@link ExecutionResult} through a {@link Builder}
|
||||
* and return a new instance with the modified values.
|
||||
* @param consumer callback to transform the result
|
||||
* @return the new response instance with the mutated {@code ExecutionResult}
|
||||
*/
|
||||
public WebOutput transform(Consumer<Builder> consumer) {
|
||||
public WebGraphQlResponse transform(Consumer<Builder> consumer) {
|
||||
Builder builder = new Builder(this);
|
||||
consumer.accept(builder);
|
||||
return builder.build();
|
||||
@@ -82,15 +81,15 @@ public class WebOutput extends DefaultExecutionGraphQlResponse {
|
||||
|
||||
|
||||
/**
|
||||
* Builder to transform a {@link WebOutput}.
|
||||
* Builder to transform a {@link WebGraphQlResponse}.
|
||||
*/
|
||||
public static final class Builder {
|
||||
|
||||
private final WebOutput original;
|
||||
private final WebGraphQlResponse original;
|
||||
|
||||
private final ExecutionResultImpl.Builder executionResultBuilder;
|
||||
|
||||
private Builder(WebOutput original) {
|
||||
private Builder(WebGraphQlResponse original) {
|
||||
this.original = original;
|
||||
this.executionResultBuilder = ExecutionResultImpl.newExecutionResult().from(original.getExecutionResult());
|
||||
}
|
||||
@@ -127,8 +126,8 @@ public class WebOutput extends DefaultExecutionGraphQlResponse {
|
||||
return this;
|
||||
}
|
||||
|
||||
public WebOutput build() {
|
||||
return new WebOutput(this.original, this.executionResultBuilder.build());
|
||||
public WebGraphQlResponse build() {
|
||||
return new WebGraphQlResponse(this.original, this.executionResultBuilder.build());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -45,12 +45,12 @@ public interface WebInterceptor {
|
||||
* of other interceptors followed by a
|
||||
* {@link org.springframework.graphql.GraphQlService} that executes the
|
||||
* request through the GraphQL Java.
|
||||
* @param webInput provides access to GraphQL request input and allows
|
||||
* customizing the {@link ExecutionInput} that will be used.
|
||||
* @param request provides access to GraphQL request and allows customization
|
||||
* of the {@link ExecutionInput} for {@link graphql.GraphQL}.
|
||||
* @param chain the rest of the chain to handle the request
|
||||
* @return a {@link Mono} with the result
|
||||
* @return a {@link Mono} with the response
|
||||
*/
|
||||
Mono<WebOutput> intercept(WebInput webInput, WebInterceptorChain chain);
|
||||
Mono<WebGraphQlResponse> intercept(WebGraphQlRequest request, WebInterceptorChain chain);
|
||||
|
||||
/**
|
||||
* Return a new {@link WebInterceptor} that invokes the current interceptor
|
||||
@@ -60,8 +60,10 @@ public interface WebInterceptor {
|
||||
*/
|
||||
default WebInterceptor andThen(WebInterceptor interceptor) {
|
||||
Assert.notNull(interceptor, "WebInterceptor is required");
|
||||
return (currentInput, next) -> intercept(currentInput,
|
||||
(nextInput) -> interceptor.intercept(nextInput, next));
|
||||
return (request, chain) -> {
|
||||
WebInterceptorChain nextChain = nextRequest -> interceptor.intercept(nextRequest, chain);
|
||||
return intercept(request, nextChain);
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,10 +30,10 @@ public interface WebInterceptorChain {
|
||||
* Delegate to the rest of the chain that consists of other interceptors
|
||||
* followed by a {@link org.springframework.graphql.GraphQlService} that
|
||||
* executes the request through the GraphQL Java.
|
||||
* @param webInput provides access to GraphQL request input and allows
|
||||
* customizing the {@link ExecutionInput} that will be used.
|
||||
* @return the output with the result from request execution
|
||||
* @param request provides access to GraphQL request and allows customizing
|
||||
* the {@link ExecutionInput} for {@link graphql.GraphQL}.
|
||||
* @return {@code Mono} with the response
|
||||
*/
|
||||
Mono<WebOutput> next(WebInput webInput);
|
||||
Mono<WebGraphQlResponse> next(WebGraphQlRequest request);
|
||||
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ import reactor.core.publisher.Mono;
|
||||
public interface WebSocketInterceptor extends WebInterceptor {
|
||||
|
||||
@Override
|
||||
default Mono<WebOutput> intercept(WebInput webInput, WebInterceptorChain chain) {
|
||||
return chain.next(webInput);
|
||||
default Mono<WebGraphQlResponse> intercept(WebGraphQlRequest request, WebInterceptorChain chain) {
|
||||
return chain.next(request);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,7 +56,7 @@ public interface WebSocketInterceptor extends WebInterceptor {
|
||||
* additional, or more centralized handling across subscriptions.
|
||||
* @param sessionId the id of the WebSocket session
|
||||
* @param subscriptionId the unique id for the subscription; correlates to the
|
||||
* {@link WebInput#getId() requestId} from the original {@code "subscribe"}
|
||||
* {@link WebGraphQlRequest#getId() requestId} from the original {@code "subscribe"}
|
||||
* message that started the subscription
|
||||
* @return {@code Mono} for the completion of handling
|
||||
*/
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
* {@link org.springframework.graphql.web.webmvc Spring WebMvc} or
|
||||
* {@link org.springframework.graphql.web.webflux Spring WebFlux} with a common
|
||||
* {@link org.springframework.graphql.web.WebInterceptor interception} model that allows
|
||||
* applications to customize request input and output.
|
||||
* applications to customize the request and response.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
|
||||
@@ -22,7 +22,6 @@ import java.util.Map;
|
||||
|
||||
import graphql.GraphQLError;
|
||||
|
||||
import org.springframework.graphql.ExecutionGraphQlResponse;
|
||||
import org.springframework.graphql.GraphQlRequest;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -174,16 +173,6 @@ public class GraphQlMessage {
|
||||
return new GraphQlMessage(id, GraphQlMessageType.SUBSCRIBE, request.toMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@code "next"} server message.
|
||||
* @param id unique request id
|
||||
* @param output the output to obtain the result map from
|
||||
*/
|
||||
public static GraphQlMessage next(String id, ExecutionGraphQlResponse output) {
|
||||
Assert.notNull(output, "ExecutionGraphQlResponse is required");
|
||||
return next(id, output.toMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@code "next"} server message.
|
||||
* @param id unique request id
|
||||
|
||||
@@ -23,8 +23,8 @@ import org.apache.commons.logging.LogFactory;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.graphql.web.WebGraphQlRequest;
|
||||
import org.springframework.graphql.web.WebGraphQlHandler;
|
||||
import org.springframework.graphql.web.WebInput;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
@@ -57,28 +57,28 @@ public class GraphQlHttpHandler {
|
||||
|
||||
/**
|
||||
* Handle GraphQL requests over HTTP.
|
||||
* @param request the incoming HTTP request
|
||||
* @param serverRequest the incoming HTTP request
|
||||
* @return the HTTP response
|
||||
*/
|
||||
public Mono<ServerResponse> handleRequest(ServerRequest request) {
|
||||
return request.bodyToMono(MAP_PARAMETERIZED_TYPE_REF)
|
||||
.flatMap((body) -> {
|
||||
WebInput input = new WebInput(
|
||||
request.uri(), request.headers().asHttpHeaders(), body,
|
||||
request.exchange().getRequest().getId(),
|
||||
request.exchange().getLocaleContext().getLocale());
|
||||
public Mono<ServerResponse> handleRequest(ServerRequest serverRequest) {
|
||||
return serverRequest.bodyToMono(MAP_PARAMETERIZED_TYPE_REF)
|
||||
.flatMap(body -> {
|
||||
WebGraphQlRequest graphQlRequest = new WebGraphQlRequest(
|
||||
serverRequest.uri(), serverRequest.headers().asHttpHeaders(), body,
|
||||
serverRequest.exchange().getRequest().getId(),
|
||||
serverRequest.exchange().getLocaleContext().getLocale());
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Executing: " + input);
|
||||
logger.debug("Executing: " + graphQlRequest);
|
||||
}
|
||||
return this.graphQlHandler.handleRequest(input);
|
||||
return this.graphQlHandler.handleRequest(graphQlRequest);
|
||||
})
|
||||
.flatMap(output -> {
|
||||
.flatMap(response -> {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Execution complete");
|
||||
}
|
||||
ServerResponse.BodyBuilder builder = ServerResponse.ok();
|
||||
builder.headers(headers -> headers.putAll(output.getResponseHeaders()));
|
||||
return builder.bodyValue(output.toMap());
|
||||
builder.headers(headers -> headers.putAll(response.getResponseHeaders()));
|
||||
return builder.bodyValue(response.toMap());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -32,9 +32,9 @@ import org.reactivestreams.Subscription;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.graphql.web.WebGraphQlRequest;
|
||||
import org.springframework.graphql.web.WebGraphQlHandler;
|
||||
import org.springframework.graphql.web.WebInput;
|
||||
import org.springframework.graphql.web.WebOutput;
|
||||
import org.springframework.graphql.web.WebGraphQlResponse;
|
||||
import org.springframework.graphql.web.WebSocketInterceptor;
|
||||
import org.springframework.graphql.web.support.GraphQlMessage;
|
||||
import org.springframework.http.codec.CodecConfigurer;
|
||||
@@ -139,13 +139,13 @@ public class GraphQlWebSocketHandler implements WebSocketHandler {
|
||||
if (id == null) {
|
||||
return GraphQlStatus.close(session, GraphQlStatus.INVALID_MESSAGE_STATUS);
|
||||
}
|
||||
WebInput input = new WebInput(
|
||||
WebGraphQlRequest request = new WebGraphQlRequest(
|
||||
handshakeInfo.getUri(), handshakeInfo.getHeaders(), payload, id, null);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Executing: " + input);
|
||||
logger.debug("Executing: " + request);
|
||||
}
|
||||
return this.graphQlHandler.handleRequest(input)
|
||||
.flatMapMany((output) -> handleWebOutput(session, id, subscriptions, output))
|
||||
return this.graphQlHandler.handleRequest(request)
|
||||
.flatMapMany(response -> handleResponse(session, id, subscriptions, response))
|
||||
.doOnTerminate(() -> subscriptions.remove(id));
|
||||
case PING:
|
||||
return Flux.just(this.codecDelegate.encode(session, GraphQlMessage.pong(null)));
|
||||
@@ -176,19 +176,19 @@ public class GraphQlWebSocketHandler implements WebSocketHandler {
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Flux<WebSocketMessage> handleWebOutput(WebSocketSession session, String id,
|
||||
Map<String, Subscription> subscriptions, WebOutput output) {
|
||||
private Flux<WebSocketMessage> handleResponse(WebSocketSession session, String id,
|
||||
Map<String, Subscription> subscriptions, WebGraphQlResponse response) {
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Execution result ready"
|
||||
+ (!CollectionUtils.isEmpty(output.getErrors()) ? " with errors: " + output.getErrors() : "")
|
||||
+ (!CollectionUtils.isEmpty(response.getErrors()) ? " with errors: " + response.getErrors() : "")
|
||||
+ ".");
|
||||
}
|
||||
|
||||
Flux<Map<String, Object>> responseFlux;
|
||||
if (output.getData() instanceof Publisher) {
|
||||
if (response.getData() instanceof Publisher) {
|
||||
// Subscription
|
||||
responseFlux = Flux.from((Publisher<ExecutionResult>) output.getData())
|
||||
responseFlux = Flux.from((Publisher<ExecutionResult>) response.getData())
|
||||
.map(ExecutionResult::toSpecification)
|
||||
.doOnSubscribe((subscription) -> {
|
||||
Subscription previous = subscriptions.putIfAbsent(id, subscription);
|
||||
@@ -199,7 +199,7 @@ public class GraphQlWebSocketHandler implements WebSocketHandler {
|
||||
}
|
||||
else {
|
||||
// Single response (query or mutation) that may contain errors
|
||||
responseFlux = Flux.just(output.toMap());
|
||||
responseFlux = Flux.just(response.toMap());
|
||||
}
|
||||
|
||||
return responseFlux
|
||||
|
||||
@@ -28,7 +28,7 @@ import reactor.core.publisher.Mono;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.graphql.web.WebGraphQlHandler;
|
||||
import org.springframework.graphql.web.WebInput;
|
||||
import org.springframework.graphql.web.WebGraphQlRequest;
|
||||
import org.springframework.util.AlternativeJdkIdGenerator;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.IdGenerator;
|
||||
@@ -67,29 +67,29 @@ public class GraphQlHttpHandler {
|
||||
|
||||
/**
|
||||
* Handle GraphQL requests over HTTP.
|
||||
* @param request the incoming HTTP request
|
||||
* @param serverRequest the incoming HTTP request
|
||||
* @return the HTTP response
|
||||
* @throws ServletException may be raised when reading the request body, e.g.
|
||||
* {@link HttpMediaTypeNotSupportedException}.
|
||||
*/
|
||||
public ServerResponse handleRequest(ServerRequest request) throws ServletException {
|
||||
public ServerResponse handleRequest(ServerRequest serverRequest) throws ServletException {
|
||||
|
||||
WebInput input = new WebInput(
|
||||
request.uri(), request.headers().asHttpHeaders(), readBody(request),
|
||||
WebGraphQlRequest graphQlRequest = new WebGraphQlRequest(
|
||||
serverRequest.uri(), serverRequest.headers().asHttpHeaders(), readBody(serverRequest),
|
||||
this.idGenerator.generateId().toString(), LocaleContextHolder.getLocale());
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Executing: " + input);
|
||||
logger.debug("Executing: " + graphQlRequest);
|
||||
}
|
||||
|
||||
Mono<ServerResponse> responseMono = this.graphQlHandler.handleRequest(input)
|
||||
.map(output -> {
|
||||
Mono<ServerResponse> responseMono = this.graphQlHandler.handleRequest(graphQlRequest)
|
||||
.map(response -> {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Execution complete");
|
||||
}
|
||||
ServerResponse.BodyBuilder builder = ServerResponse.ok();
|
||||
builder.headers(headers -> headers.putAll(output.getResponseHeaders()));
|
||||
return builder.body(output.toMap());
|
||||
builder.headers(headers -> headers.putAll(response.getResponseHeaders()));
|
||||
return builder.body(response.toMap());
|
||||
});
|
||||
|
||||
return ServerResponse.async(responseMono);
|
||||
|
||||
@@ -44,8 +44,8 @@ import reactor.core.scheduler.Scheduler;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
|
||||
import org.springframework.graphql.web.WebGraphQlHandler;
|
||||
import org.springframework.graphql.web.WebInput;
|
||||
import org.springframework.graphql.web.WebOutput;
|
||||
import org.springframework.graphql.web.WebGraphQlRequest;
|
||||
import org.springframework.graphql.web.WebGraphQlResponse;
|
||||
import org.springframework.graphql.web.WebSocketInterceptor;
|
||||
import org.springframework.graphql.web.support.GraphQlMessage;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
@@ -156,12 +156,12 @@ public class GraphQlWebSocketHandler extends TextWebSocketHandler implements Sub
|
||||
URI uri = session.getUri();
|
||||
Assert.notNull(uri, "Expected handshake url");
|
||||
HttpHeaders headers = session.getHandshakeHeaders();
|
||||
WebInput input = new WebInput(uri, headers, payload, id, null);
|
||||
WebGraphQlRequest request = new WebGraphQlRequest(uri, headers, payload, id, null);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Executing: " + input);
|
||||
logger.debug("Executing: " + request);
|
||||
}
|
||||
this.graphQlHandler.handleRequest(input)
|
||||
.flatMapMany((output) -> handleWebOutput(session, input.getId(), output))
|
||||
this.graphQlHandler.handleRequest(request)
|
||||
.flatMapMany((response) -> handleResponse(session, request.getId(), response))
|
||||
.publishOn(sessionState.getScheduler()) // Serial blocking send via single thread
|
||||
.subscribe(new SendMessageSubscriber(id, session, sessionState));
|
||||
return;
|
||||
@@ -219,16 +219,16 @@ public class GraphQlWebSocketHandler extends TextWebSocketHandler implements Sub
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Flux<TextMessage> handleWebOutput(WebSocketSession session, String id, WebOutput output) {
|
||||
private Flux<TextMessage> handleResponse(WebSocketSession session, String id, WebGraphQlResponse response) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Execution result ready"
|
||||
+ (!CollectionUtils.isEmpty(output.getErrors()) ? " with errors: " + output.getErrors() : "")
|
||||
+ (!CollectionUtils.isEmpty(response.getErrors()) ? " with errors: " + response.getErrors() : "")
|
||||
+ ".");
|
||||
}
|
||||
Flux<Map<String, Object>> responseFlux;
|
||||
if (output.getData() instanceof Publisher) {
|
||||
if (response.getData() instanceof Publisher) {
|
||||
// Subscription
|
||||
responseFlux = Flux.from((Publisher<ExecutionResult>) output.getData())
|
||||
responseFlux = Flux.from((Publisher<ExecutionResult>) response.getData())
|
||||
.map(ExecutionResult::toSpecification)
|
||||
.doOnSubscribe((subscription) -> {
|
||||
Subscription prev = getSessionInfo(session).getSubscriptions().putIfAbsent(id, subscription);
|
||||
@@ -239,7 +239,7 @@ public class GraphQlWebSocketHandler extends TextWebSocketHandler implements Sub
|
||||
}
|
||||
else {
|
||||
// Single response (query or mutation) that may contain errors
|
||||
responseFlux = Flux.just(output.toMap());
|
||||
responseFlux = Flux.just(response.toMap());
|
||||
}
|
||||
|
||||
return responseFlux
|
||||
|
||||
@@ -37,10 +37,10 @@ import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.graphql.ExecutionGraphQlResponse;
|
||||
import org.springframework.graphql.support.DefaultExecutionGraphQlResponse;
|
||||
import org.springframework.graphql.support.DocumentSource;
|
||||
import org.springframework.graphql.web.WebGraphQlRequest;
|
||||
import org.springframework.graphql.web.TestWebSocketClient;
|
||||
import org.springframework.graphql.web.TestWebSocketConnection;
|
||||
import org.springframework.graphql.web.WebGraphQlHandler;
|
||||
import org.springframework.graphql.web.WebInput;
|
||||
import org.springframework.graphql.web.WebInterceptor;
|
||||
import org.springframework.graphql.web.webflux.GraphQlHttpHandler;
|
||||
import org.springframework.graphql.web.webflux.GraphQlWebSocketHandler;
|
||||
@@ -99,24 +99,24 @@ public class WebGraphQlClientBuilderTests {
|
||||
WebGraphQlClient client = builder.build();
|
||||
client.document(DOCUMENT).execute().block(TIMEOUT);
|
||||
|
||||
WebInput input = builderSetup.getWebInput();
|
||||
assertThat(input.getUri().toString()).isEqualTo(url);
|
||||
assertThat(input.getHeaders().get("h")).containsExactly("one");
|
||||
WebGraphQlRequest request = builderSetup.getWebGraphQlRequest();
|
||||
assertThat(request.getUri().toString()).isEqualTo(url);
|
||||
assertThat(request.getHeaders().get("h")).containsExactly("one");
|
||||
|
||||
// Mutate to add header value
|
||||
builder = client.mutate().headers(headers -> headers.add("h", "two"));
|
||||
client = builder.build();
|
||||
client.document(DOCUMENT).execute().block(TIMEOUT);
|
||||
assertThat(builderSetup.getWebInput().getHeaders().get("h")).containsExactly("one", "two");
|
||||
assertThat(builderSetup.getWebGraphQlRequest().getHeaders().get("h")).containsExactly("one", "two");
|
||||
|
||||
// Mutate to replace header
|
||||
builder = client.mutate().header("h", "three", "four");
|
||||
client = builder.build();
|
||||
client.document(DOCUMENT).execute().block(TIMEOUT);
|
||||
|
||||
input = builderSetup.getWebInput();
|
||||
assertThat(input.getUri().toString()).isEqualTo(url);
|
||||
assertThat(input.getHeaders().get("h")).containsExactly("three", "four");
|
||||
request = builderSetup.getWebGraphQlRequest();
|
||||
assertThat(request.getUri().toString()).isEqualTo(url);
|
||||
assertThat(request.getHeaders().get("h")).containsExactly("three", "four");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -129,7 +129,7 @@ public class WebGraphQlClientBuilderTests {
|
||||
|
||||
HttpGraphQlClient client = builder.build();
|
||||
client.document(DOCUMENT).execute().block(TIMEOUT);
|
||||
assertThat(clientSetup.getWebInput().getHeaders().get("h")).containsExactly("one");
|
||||
assertThat(clientSetup.getWebGraphQlRequest().getHeaders().get("h")).containsExactly("one");
|
||||
|
||||
// Mutate to add header value
|
||||
HttpGraphQlClient.Builder<?> builder2 = client.mutate()
|
||||
@@ -137,7 +137,7 @@ public class WebGraphQlClientBuilderTests {
|
||||
|
||||
client = builder2.build();
|
||||
client.document(DOCUMENT).execute().block(TIMEOUT);
|
||||
assertThat(clientSetup.getWebInput().getHeaders().get("h")).containsExactly("one", "two");
|
||||
assertThat(clientSetup.getWebGraphQlRequest().getHeaders().get("h")).containsExactly("one", "two");
|
||||
|
||||
// Mutate to replace header
|
||||
HttpGraphQlClient.Builder<?> builder3 = client.mutate()
|
||||
@@ -145,7 +145,7 @@ public class WebGraphQlClientBuilderTests {
|
||||
|
||||
client = builder3.build();
|
||||
client.document(DOCUMENT).execute().block(TIMEOUT);
|
||||
assertThat(clientSetup.getWebInput().getHeaders().get("h")).containsExactly("three");
|
||||
assertThat(clientSetup.getWebGraphQlRequest().getHeaders().get("h")).containsExactly("three");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@@ -160,15 +160,15 @@ public class WebGraphQlClientBuilderTests {
|
||||
WebGraphQlClient client = builder.build();
|
||||
client.documentName("name").execute().block(TIMEOUT);
|
||||
|
||||
WebInput input = builderSetup.getWebInput();
|
||||
assertThat(input.getDocument()).isEqualTo(DOCUMENT);
|
||||
WebGraphQlRequest request = builderSetup.getWebGraphQlRequest();
|
||||
assertThat(request.getDocument()).isEqualTo(DOCUMENT);
|
||||
|
||||
// Mutate
|
||||
client = client.mutate().build();
|
||||
client.documentName("name").execute().block(TIMEOUT);
|
||||
|
||||
input = builderSetup.getWebInput();
|
||||
assertThat(input.getDocument()).isEqualTo(DOCUMENT);
|
||||
request = builderSetup.getWebGraphQlRequest();
|
||||
assertThat(request.getDocument()).isEqualTo(DOCUMENT);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@@ -178,7 +178,7 @@ public class WebGraphQlClientBuilderTests {
|
||||
WebGraphQlClient client = builderSetup.initBuilder().url("/graphql one").build();
|
||||
client.document(DOCUMENT).execute().block(TIMEOUT);
|
||||
|
||||
assertThat(builderSetup.getWebInput().getUri().toString()).isEqualTo("/graphql%20one");
|
||||
assertThat(builderSetup.getWebGraphQlRequest().getUri().toString()).isEqualTo("/graphql%20one");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@@ -215,14 +215,14 @@ public class WebGraphQlClientBuilderTests {
|
||||
|
||||
void setMockResponse(String document, ExecutionResult result);
|
||||
|
||||
WebInput getWebInput();
|
||||
WebGraphQlRequest getWebGraphQlRequest();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private abstract static class AbstractBuilderSetup implements ClientBuilderSetup {
|
||||
|
||||
private WebInput webInput;
|
||||
private WebGraphQlRequest graphQlRequest;
|
||||
|
||||
private final Map<String, ExecutionGraphQlResponse> responses = new HashMap<>();
|
||||
|
||||
@@ -242,9 +242,9 @@ public class WebGraphQlClientBuilderTests {
|
||||
Assert.notNull(response, "Unexpected request: " + document);
|
||||
return Mono.just(response);
|
||||
})
|
||||
.interceptor((input, chain) -> {
|
||||
this.webInput = input;
|
||||
return chain.next(webInput);
|
||||
.interceptor((request, chain) -> {
|
||||
this.graphQlRequest = request;
|
||||
return chain.next(graphQlRequest);
|
||||
})
|
||||
.build();
|
||||
}
|
||||
@@ -256,8 +256,8 @@ public class WebGraphQlClientBuilderTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebInput getWebInput() {
|
||||
return this.webInput;
|
||||
public WebGraphQlRequest getWebGraphQlRequest() {
|
||||
return this.graphQlRequest;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -43,13 +43,13 @@ import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.data.repository.Repository;
|
||||
import org.springframework.graphql.Author;
|
||||
import org.springframework.graphql.BookSource;
|
||||
import org.springframework.graphql.ResponseHelper;
|
||||
import org.springframework.graphql.GraphQlSetup;
|
||||
import org.springframework.graphql.ResponseHelper;
|
||||
import org.springframework.graphql.data.GraphQlRepository;
|
||||
import org.springframework.graphql.execution.RuntimeWiringConfigurer;
|
||||
import org.springframework.graphql.web.WebGraphQlRequest;
|
||||
import org.springframework.graphql.web.WebGraphQlHandler;
|
||||
import org.springframework.graphql.web.WebInput;
|
||||
import org.springframework.graphql.web.WebOutput;
|
||||
import org.springframework.graphql.web.WebGraphQlResponse;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
@@ -76,8 +76,9 @@ class QuerydslDataFetcherTests {
|
||||
mockRepository.save(book);
|
||||
|
||||
Consumer<GraphQlSetup> tester = setup -> {
|
||||
Mono<WebOutput> output = setup.toWebGraphQlHandler().handleRequest(input("{ bookById(id: 42) {name}}"));
|
||||
Book actualBook = ResponseHelper.forResponse(output).toEntity("bookById", Book.class);
|
||||
WebGraphQlRequest request = request("{ bookById(id: 42) {name}}");
|
||||
Mono<WebGraphQlResponse> responseMono = setup.toWebGraphQlHandler().handleRequest(request);
|
||||
Book actualBook = ResponseHelper.forResponse(responseMono).toEntity("bookById", Book.class);
|
||||
|
||||
assertThat(actualBook.getName()).isEqualTo(book.getName());
|
||||
};
|
||||
@@ -96,9 +97,10 @@ class QuerydslDataFetcherTests {
|
||||
mockRepository.saveAll(Arrays.asList(book1, book2));
|
||||
|
||||
Consumer<GraphQlSetup> tester = graphQlSetup -> {
|
||||
Mono<WebOutput> output = graphQlSetup.toWebGraphQlHandler().handleRequest(input("{ books {name}}"));
|
||||
WebGraphQlRequest request = request("{ books {name}}");
|
||||
Mono<WebGraphQlResponse> responseMono = graphQlSetup.toWebGraphQlHandler().handleRequest(request);
|
||||
|
||||
List<String> names = ResponseHelper.forResponse(output).toList("books", Book.class)
|
||||
List<String> names = ResponseHelper.forResponse(responseMono).toList("books", Book.class)
|
||||
.stream().map(Book::getName).collect(Collectors.toList());
|
||||
|
||||
assertThat(names).containsExactlyInAnyOrder(book1.getName(), book2.getName());
|
||||
@@ -117,10 +119,10 @@ class QuerydslDataFetcherTests {
|
||||
Book book2 = new Book(53L, "Breaking Bad", new Author(0L, "", "Heisenberg"));
|
||||
mockRepository.saveAll(Arrays.asList(book1, book2));
|
||||
|
||||
Mono<WebOutput> output = graphQlSetup(mockRepository).toWebGraphQlHandler()
|
||||
.handleRequest(input("{ booksById(id: [42,53]) {name}}"));
|
||||
Mono<WebGraphQlResponse> responseMono = graphQlSetup(mockRepository).toWebGraphQlHandler()
|
||||
.handleRequest(request("{ booksById(id: [42,53]) {name}}"));
|
||||
|
||||
List<String> names = ResponseHelper.forResponse(output).toList("booksById", Book.class)
|
||||
List<String> names = ResponseHelper.forResponse(responseMono).toList("booksById", Book.class)
|
||||
.stream().map(Book::getName).collect(Collectors.toList());
|
||||
|
||||
assertThat(names).containsExactlyInAnyOrder(book1.getName(), book2.getName());
|
||||
@@ -134,9 +136,10 @@ class QuerydslDataFetcherTests {
|
||||
repository.saveAll(Arrays.asList(book1, book2));
|
||||
|
||||
Consumer<GraphQlSetup> tester = graphQlSetup -> {
|
||||
Mono<WebOutput> output = graphQlSetup.toWebGraphQlHandler().handleRequest(input("{ books {name}}"));
|
||||
WebGraphQlRequest request = request("{ books {name}}");
|
||||
Mono<WebGraphQlResponse> responseMono = graphQlSetup.toWebGraphQlHandler().handleRequest(request);
|
||||
|
||||
List<String> names = ResponseHelper.forResponse(output).toList("books", Book.class)
|
||||
List<String> names = ResponseHelper.forResponse(responseMono).toList("books", Book.class)
|
||||
.stream().map(Book::getName).collect(Collectors.toList());
|
||||
|
||||
assertThat(names).containsExactlyInAnyOrder(book1.getName(), book2.getName());
|
||||
@@ -159,7 +162,7 @@ class QuerydslDataFetcherTests {
|
||||
.many();
|
||||
|
||||
graphQlSetup("books", fetcher).toWebGraphQlHandler()
|
||||
.handleRequest(input("{ books(name: \"H\", author: \"Doug\") {name}}"))
|
||||
.handleRequest(request("{ books(name: \"H\", author: \"Doug\") {name}}"))
|
||||
.block();
|
||||
|
||||
ArgumentCaptor<Predicate> predicateCaptor = ArgumentCaptor.forClass(Predicate.class);
|
||||
@@ -177,9 +180,9 @@ class QuerydslDataFetcherTests {
|
||||
|
||||
// 1) Automatic registration only
|
||||
WebGraphQlHandler handler = graphQlSetup(mockRepository).toWebGraphQlHandler();
|
||||
Mono<WebOutput> outputMono = handler.handleRequest(input("{ bookById(id: 1) {name}}"));
|
||||
Mono<WebGraphQlResponse> responseMono = handler.handleRequest(request("{ bookById(id: 1) {name}}"));
|
||||
|
||||
Book actualBook = ResponseHelper.forResponse(outputMono).toEntity("bookById", Book.class);
|
||||
Book actualBook = ResponseHelper.forResponse(responseMono).toEntity("bookById", Book.class);
|
||||
assertThat(actualBook.getName()).isEqualTo("Hitchhiker's Guide to the Galaxy");
|
||||
|
||||
// 2) Automatic registration and explicit wiring
|
||||
@@ -187,9 +190,9 @@ class QuerydslDataFetcherTests {
|
||||
.queryFetcher("bookById", env -> new Book(53L, "Breaking Bad", new Author(0L, "", "Heisenberg")))
|
||||
.toWebGraphQlHandler();
|
||||
|
||||
outputMono = handler.handleRequest(input("{ bookById(id: 1) {name}}"));
|
||||
responseMono = handler.handleRequest(request("{ bookById(id: 1) {name}}"));
|
||||
|
||||
actualBook = ResponseHelper.forResponse(outputMono).toEntity("bookById", Book.class);
|
||||
actualBook = ResponseHelper.forResponse(responseMono).toEntity("bookById", Book.class);
|
||||
assertThat(actualBook.getName()).isEqualTo("Breaking Bad");
|
||||
}
|
||||
|
||||
@@ -201,9 +204,9 @@ class QuerydslDataFetcherTests {
|
||||
DataFetcher<?> fetcher = QuerydslDataFetcher.builder(mockRepository).projectAs(BookProjection.class).single();
|
||||
WebGraphQlHandler handler = graphQlSetup("bookById", fetcher).toWebGraphQlHandler();
|
||||
|
||||
Mono<WebOutput> outputMono = handler.handleRequest(input("{ bookById(id: 42) {name}}"));
|
||||
Mono<WebGraphQlResponse> responseMono = handler.handleRequest(request("{ bookById(id: 42) {name}}"));
|
||||
|
||||
Book actualBook = ResponseHelper.forResponse(outputMono).toEntity("bookById", Book.class);
|
||||
Book actualBook = ResponseHelper.forResponse(responseMono).toEntity("bookById", Book.class);
|
||||
assertThat(actualBook.getName()).isEqualTo("Hitchhiker's Guide to the Galaxy by Douglas Adams");
|
||||
}
|
||||
|
||||
@@ -215,9 +218,9 @@ class QuerydslDataFetcherTests {
|
||||
DataFetcher<?> fetcher = QuerydslDataFetcher.builder(mockRepository).projectAs(BookDto.class).single();
|
||||
WebGraphQlHandler handler = graphQlSetup("bookById", fetcher).toWebGraphQlHandler();
|
||||
|
||||
Mono<WebOutput> outputMono = handler.handleRequest(input("{ bookById(id: 42) {name}}"));
|
||||
Mono<WebGraphQlResponse> responseMono = handler.handleRequest(request("{ bookById(id: 42) {name}}"));
|
||||
|
||||
Book actualBook = ResponseHelper.forResponse(outputMono).toEntity("bookById", Book.class);
|
||||
Book actualBook = ResponseHelper.forResponse(responseMono).toEntity("bookById", Book.class);
|
||||
assertThat(actualBook.getName()).isEqualTo("The book is: Hitchhiker's Guide to the Galaxy");
|
||||
}
|
||||
|
||||
@@ -228,8 +231,9 @@ class QuerydslDataFetcherTests {
|
||||
when(mockRepository.findBy(any(), any())).thenReturn(Mono.just(book));
|
||||
|
||||
Consumer<GraphQlSetup> tester = setup -> {
|
||||
Mono<WebOutput> outputMono = setup.toWebGraphQlHandler().handleRequest(input("{ bookById(id: 1) {name}}"));
|
||||
Book actualBook = ResponseHelper.forResponse(outputMono).toEntity("bookById", Book.class);
|
||||
WebGraphQlRequest request = request("{ bookById(id: 1) {name}}");
|
||||
Mono<WebGraphQlResponse> responseMono = setup.toWebGraphQlHandler().handleRequest(request);
|
||||
Book actualBook = ResponseHelper.forResponse(responseMono).toEntity("bookById", Book.class);
|
||||
|
||||
assertThat(actualBook.getName()).isEqualTo(book.getName());
|
||||
};
|
||||
@@ -249,9 +253,10 @@ class QuerydslDataFetcherTests {
|
||||
when(mockRepository.findBy(any(), any())).thenReturn(Flux.just(book1, book2));
|
||||
|
||||
Consumer<GraphQlSetup> tester = setup -> {
|
||||
Mono<WebOutput> outputMono = setup.toWebGraphQlHandler().handleRequest(input("{ books {name}}"));
|
||||
WebGraphQlRequest request = request("{ books {name}}");
|
||||
Mono<WebGraphQlResponse> responseMono = setup.toWebGraphQlHandler().handleRequest(request);
|
||||
|
||||
List<String> names = ResponseHelper.forResponse(outputMono).toList("books", Book.class)
|
||||
List<String> names = ResponseHelper.forResponse(responseMono).toList("books", Book.class)
|
||||
.stream().map(Book::getName).collect(Collectors.toList());
|
||||
|
||||
assertThat(names).containsExactlyInAnyOrder("Breaking Bad", "Hitchhiker's Guide to the Galaxy");
|
||||
@@ -287,8 +292,9 @@ class QuerydslDataFetcherTests {
|
||||
return GraphQlSetup.schemaResource(BookSource.schema).runtimeWiring(configurer);
|
||||
}
|
||||
|
||||
private WebInput input(String query) {
|
||||
return new WebInput(URI.create("/"), new HttpHeaders(), Collections.singletonMap("query", query), "1", null);
|
||||
private WebGraphQlRequest request(String query) {
|
||||
return new WebGraphQlRequest(
|
||||
URI.create("/"), new HttpHeaders(), Collections.singletonMap("query", query), "1", null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -40,13 +40,13 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.data.repository.query.QueryByExampleExecutor;
|
||||
import org.springframework.graphql.BookSource;
|
||||
import org.springframework.graphql.ResponseHelper;
|
||||
import org.springframework.graphql.GraphQlSetup;
|
||||
import org.springframework.graphql.ResponseHelper;
|
||||
import org.springframework.graphql.data.query.QueryByExampleDataFetcher;
|
||||
import org.springframework.graphql.execution.RuntimeWiringConfigurer;
|
||||
import org.springframework.graphql.web.WebGraphQlRequest;
|
||||
import org.springframework.graphql.web.WebGraphQlHandler;
|
||||
import org.springframework.graphql.web.WebInput;
|
||||
import org.springframework.graphql.web.WebOutput;
|
||||
import org.springframework.graphql.web.WebGraphQlResponse;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
import org.springframework.lang.Nullable;
|
||||
@@ -79,8 +79,9 @@ class QueryByExampleDataFetcherJpaTests {
|
||||
repository.save(book);
|
||||
|
||||
Consumer<GraphQlSetup> tester = setup -> {
|
||||
Mono<WebOutput> output = setup.toWebGraphQlHandler().handleRequest(input("{ bookById(id: 42) {name}}"));
|
||||
Book actualBook = ResponseHelper.forResponse(output).toEntity("bookById", Book.class);
|
||||
WebGraphQlRequest request = request("{ bookById(id: 42) {name}}");
|
||||
Mono<WebGraphQlResponse> responseMono = setup.toWebGraphQlHandler().handleRequest(request);
|
||||
Book actualBook = ResponseHelper.forResponse(responseMono).toEntity("bookById", Book.class);
|
||||
|
||||
assertThat(actualBook.getName()).isEqualTo(book.getName());
|
||||
};
|
||||
@@ -99,9 +100,10 @@ class QueryByExampleDataFetcherJpaTests {
|
||||
repository.saveAll(Arrays.asList(book1, book2));
|
||||
|
||||
Consumer<GraphQlSetup> tester = graphQlSetup -> {
|
||||
Mono<WebOutput> output = graphQlSetup.toWebGraphQlHandler().handleRequest(input("{ books {name}}"));
|
||||
WebGraphQlRequest request = request("{ books {name}}");
|
||||
Mono<WebGraphQlResponse> responseMono = graphQlSetup.toWebGraphQlHandler().handleRequest(request);
|
||||
|
||||
List<String> names = ResponseHelper.forResponse(output).toList("books", Book.class)
|
||||
List<String> names = ResponseHelper.forResponse(responseMono).toList("books", Book.class)
|
||||
.stream()
|
||||
.map(Book::getName)
|
||||
.collect(Collectors.toList());
|
||||
@@ -124,9 +126,9 @@ class QueryByExampleDataFetcherJpaTests {
|
||||
|
||||
// 1) Automatic registration only
|
||||
WebGraphQlHandler handler = graphQlSetup(mockRepository).toWebGraphQlHandler();
|
||||
Mono<WebOutput> outputMono = handler.handleRequest(input("{ bookById(id: 1) {name}}"));
|
||||
Mono<WebGraphQlResponse> responseMono = handler.handleRequest(request("{ bookById(id: 1) {name}}"));
|
||||
|
||||
Book actualBook = ResponseHelper.forResponse(outputMono).toEntity("bookById", Book.class);
|
||||
Book actualBook = ResponseHelper.forResponse(responseMono).toEntity("bookById", Book.class);
|
||||
assertThat(actualBook.getName()).isEqualTo("Hitchhiker's Guide to the Galaxy");
|
||||
|
||||
// 2) Automatic registration and explicit wiring
|
||||
@@ -134,9 +136,9 @@ class QueryByExampleDataFetcherJpaTests {
|
||||
.queryFetcher("bookById", env -> new Book(53L, "Breaking Bad", new Author(0L, "", "Heisenberg")))
|
||||
.toWebGraphQlHandler();
|
||||
|
||||
outputMono = handler.handleRequest(input("{ bookById(id: 1) {name}}"));
|
||||
responseMono = handler.handleRequest(request("{ bookById(id: 1) {name}}"));
|
||||
|
||||
actualBook = ResponseHelper.forResponse(outputMono).toEntity("bookById", Book.class);
|
||||
actualBook = ResponseHelper.forResponse(responseMono).toEntity("bookById", Book.class);
|
||||
assertThat(actualBook.getName()).isEqualTo("Breaking Bad");
|
||||
}
|
||||
|
||||
@@ -148,9 +150,9 @@ class QueryByExampleDataFetcherJpaTests {
|
||||
DataFetcher<?> fetcher = QueryByExampleDataFetcher.builder(repository).projectAs(BookProjection.class).single();
|
||||
WebGraphQlHandler handler = graphQlSetup("bookById", fetcher).toWebGraphQlHandler();
|
||||
|
||||
Mono<WebOutput> outputMono = handler.handleRequest(input("{ bookById(id: 42) {name}}"));
|
||||
Mono<WebGraphQlResponse> responseMono = handler.handleRequest(request("{ bookById(id: 42) {name}}"));
|
||||
|
||||
Book actualBook = ResponseHelper.forResponse(outputMono).toEntity("bookById", Book.class);
|
||||
Book actualBook = ResponseHelper.forResponse(responseMono).toEntity("bookById", Book.class);
|
||||
assertThat(actualBook.getName()).isEqualTo("Hitchhiker's Guide to the Galaxy by Douglas Adams");
|
||||
}
|
||||
|
||||
@@ -163,9 +165,9 @@ class QueryByExampleDataFetcherJpaTests {
|
||||
DataFetcher<?> fetcher = QueryByExampleDataFetcher.builder(repository).projectAs(BookDto.class).single();
|
||||
WebGraphQlHandler handler = graphQlSetup("bookById", fetcher).toWebGraphQlHandler();
|
||||
|
||||
Mono<WebOutput> outputMono = handler.handleRequest(input("{ bookById(id: 42) {name}}"));
|
||||
Mono<WebGraphQlResponse> responseMono = handler.handleRequest(request("{ bookById(id: 42) {name}}"));
|
||||
|
||||
Book actualBook = ResponseHelper.forResponse(outputMono).toEntity("bookById", Book.class);
|
||||
Book actualBook = ResponseHelper.forResponse(responseMono).toEntity("bookById", Book.class);
|
||||
assertThat(actualBook.getName()).isEqualTo("The book is: Hitchhiker's Guide to the Galaxy");
|
||||
}
|
||||
|
||||
@@ -186,8 +188,9 @@ class QueryByExampleDataFetcherJpaTests {
|
||||
return GraphQlSetup.schemaResource(BookSource.schema).runtimeWiring(configurer);
|
||||
}
|
||||
|
||||
private WebInput input(String query) {
|
||||
return new WebInput(URI.create("/"), new HttpHeaders(), Collections.singletonMap("query", query), "1", null);
|
||||
private WebGraphQlRequest request(String query) {
|
||||
return new WebGraphQlRequest(
|
||||
URI.create("/"), new HttpHeaders(), Collections.singletonMap("query", query), "1", null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -47,8 +47,8 @@ import org.springframework.graphql.GraphQlSetup;
|
||||
import org.springframework.graphql.data.query.QueryByExampleDataFetcher;
|
||||
import org.springframework.graphql.execution.RuntimeWiringConfigurer;
|
||||
import org.springframework.graphql.web.WebGraphQlHandler;
|
||||
import org.springframework.graphql.web.WebInput;
|
||||
import org.springframework.graphql.web.WebOutput;
|
||||
import org.springframework.graphql.web.WebGraphQlRequest;
|
||||
import org.springframework.graphql.web.WebGraphQlResponse;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
@@ -80,8 +80,9 @@ class QueryByExampleDataFetcherMongoDbTests {
|
||||
repository.save(book);
|
||||
|
||||
Consumer<GraphQlSetup> tester = setup -> {
|
||||
Mono<WebOutput> output = setup.toWebGraphQlHandler().handleRequest(input("{ bookById(id: 42) {name}}"));
|
||||
Book actualBook = ResponseHelper.forResponse(output).toEntity("bookById", Book.class);
|
||||
WebGraphQlRequest request = request("{ bookById(id: 42) {name}}");
|
||||
Mono<WebGraphQlResponse> responseMono = setup.toWebGraphQlHandler().handleRequest(request);
|
||||
Book actualBook = ResponseHelper.forResponse(responseMono).toEntity("bookById", Book.class);
|
||||
|
||||
assertThat(actualBook.getName()).isEqualTo(book.getName());
|
||||
};
|
||||
@@ -100,9 +101,10 @@ class QueryByExampleDataFetcherMongoDbTests {
|
||||
repository.saveAll(Arrays.asList(book1, book2));
|
||||
|
||||
Consumer<GraphQlSetup> tester = graphQlSetup -> {
|
||||
Mono<WebOutput> output = graphQlSetup.toWebGraphQlHandler().handleRequest(input("{ books {name}}"));
|
||||
WebGraphQlRequest request = request("{ books {name}}");
|
||||
Mono<WebGraphQlResponse> responseMono = graphQlSetup.toWebGraphQlHandler().handleRequest(request);
|
||||
|
||||
List<String> names = ResponseHelper.forResponse(output).toList("books", Book.class)
|
||||
List<String> names = ResponseHelper.forResponse(responseMono).toList("books", Book.class)
|
||||
.stream().map(Book::getName).collect(Collectors.toList());
|
||||
|
||||
assertThat(names).containsExactlyInAnyOrder(book1.getName(), book2.getName());
|
||||
@@ -123,9 +125,9 @@ class QueryByExampleDataFetcherMongoDbTests {
|
||||
|
||||
// 1) Automatic registration only
|
||||
WebGraphQlHandler handler = graphQlSetup(mockRepository).toWebGraphQlHandler();
|
||||
Mono<WebOutput> outputMono = handler.handleRequest(input("{ bookById(id: 1) {name}}"));
|
||||
Mono<WebGraphQlResponse> responseMono = handler.handleRequest(request("{ bookById(id: 1) {name}}"));
|
||||
|
||||
Book actualBook = ResponseHelper.forResponse(outputMono).toEntity("bookById", Book.class);
|
||||
Book actualBook = ResponseHelper.forResponse(responseMono).toEntity("bookById", Book.class);
|
||||
assertThat(actualBook.getName()).isEqualTo("Hitchhiker's Guide to the Galaxy");
|
||||
|
||||
// 2) Automatic registration and explicit wiring
|
||||
@@ -133,9 +135,9 @@ class QueryByExampleDataFetcherMongoDbTests {
|
||||
.queryFetcher("bookById", env -> new Book("53", "Breaking Bad", new Author("0", "", "Heisenberg")))
|
||||
.toWebGraphQlHandler();
|
||||
|
||||
outputMono = handler.handleRequest(input("{ bookById(id: 1) {name}}"));
|
||||
responseMono = handler.handleRequest(request("{ bookById(id: 1) {name}}"));
|
||||
|
||||
actualBook = ResponseHelper.forResponse(outputMono).toEntity("bookById", Book.class);
|
||||
actualBook = ResponseHelper.forResponse(responseMono).toEntity("bookById", Book.class);
|
||||
assertThat(actualBook.getName()).isEqualTo("Breaking Bad");
|
||||
}
|
||||
|
||||
@@ -147,9 +149,9 @@ class QueryByExampleDataFetcherMongoDbTests {
|
||||
DataFetcher<?> fetcher = QueryByExampleDataFetcher.builder(repository).projectAs(BookProjection.class).single();
|
||||
WebGraphQlHandler handler = graphQlSetup("bookById", fetcher).toWebGraphQlHandler();
|
||||
|
||||
Mono<WebOutput> outputMono = handler.handleRequest(input("{ bookById(id: 42) {name}}"));
|
||||
Mono<WebGraphQlResponse> responseMono = handler.handleRequest(request("{ bookById(id: 42) {name}}"));
|
||||
|
||||
Book actualBook = ResponseHelper.forResponse(outputMono).toEntity("bookById", Book.class);
|
||||
Book actualBook = ResponseHelper.forResponse(responseMono).toEntity("bookById", Book.class);
|
||||
assertThat(actualBook.getName()).isEqualTo("Hitchhiker's Guide to the Galaxy by Douglas Adams");
|
||||
}
|
||||
|
||||
@@ -161,9 +163,9 @@ class QueryByExampleDataFetcherMongoDbTests {
|
||||
DataFetcher<?> fetcher = QueryByExampleDataFetcher.builder(repository).projectAs(BookDto.class).single();
|
||||
WebGraphQlHandler handler = graphQlSetup("bookById", fetcher).toWebGraphQlHandler();
|
||||
|
||||
Mono<WebOutput> outputMono = handler.handleRequest(input("{ bookById(id: 42) {name}}"));
|
||||
Mono<WebGraphQlResponse> responseMono = handler.handleRequest(request("{ bookById(id: 42) {name}}"));
|
||||
|
||||
Book actualBook = ResponseHelper.forResponse(outputMono).toEntity("bookById", Book.class);
|
||||
Book actualBook = ResponseHelper.forResponse(responseMono).toEntity("bookById", Book.class);
|
||||
assertThat(actualBook.getName()).isEqualTo("The book is: Hitchhiker's Guide to the Galaxy");
|
||||
}
|
||||
|
||||
@@ -184,8 +186,9 @@ class QueryByExampleDataFetcherMongoDbTests {
|
||||
return GraphQlSetup.schemaResource(BookSource.schema).runtimeWiring(configurer);
|
||||
}
|
||||
|
||||
private WebInput input(String query) {
|
||||
return new WebInput(URI.create("/"), new HttpHeaders(), Collections.singletonMap("query", query), "1", null);
|
||||
private WebGraphQlRequest request(String query) {
|
||||
return new WebGraphQlRequest(
|
||||
URI.create("/"), new HttpHeaders(), Collections.singletonMap("query", query), "1", null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -41,13 +41,13 @@ import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
|
||||
import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories;
|
||||
import org.springframework.data.repository.query.ReactiveQueryByExampleExecutor;
|
||||
import org.springframework.graphql.BookSource;
|
||||
import org.springframework.graphql.ResponseHelper;
|
||||
import org.springframework.graphql.GraphQlSetup;
|
||||
import org.springframework.graphql.ResponseHelper;
|
||||
import org.springframework.graphql.data.query.QueryByExampleDataFetcher;
|
||||
import org.springframework.graphql.execution.RuntimeWiringConfigurer;
|
||||
import org.springframework.graphql.web.WebGraphQlRequest;
|
||||
import org.springframework.graphql.web.WebGraphQlHandler;
|
||||
import org.springframework.graphql.web.WebInput;
|
||||
import org.springframework.graphql.web.WebOutput;
|
||||
import org.springframework.graphql.web.WebGraphQlResponse;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
@@ -76,8 +76,9 @@ class QueryByExampleDataFetcherReactiveMongoDbTests {
|
||||
repository.save(book).block();
|
||||
|
||||
Consumer<GraphQlSetup> tester = setup -> {
|
||||
Mono<WebOutput> outputMono = setup.toWebGraphQlHandler().handleRequest(input("{ bookById(id: 42) {name}}"));
|
||||
Book actualBook = ResponseHelper.forResponse(outputMono).toEntity("bookById", Book.class);
|
||||
WebGraphQlRequest request = request("{ bookById(id: 42) {name}}");
|
||||
Mono<WebGraphQlResponse> responseMono = setup.toWebGraphQlHandler().handleRequest(request);
|
||||
Book actualBook = ResponseHelper.forResponse(responseMono).toEntity("bookById", Book.class);
|
||||
|
||||
assertThat(actualBook.getName()).isEqualTo(book.getName());
|
||||
};
|
||||
@@ -97,9 +98,9 @@ class QueryByExampleDataFetcherReactiveMongoDbTests {
|
||||
DataFetcher<?> fetcher = QueryByExampleDataFetcher.builder(repository).projectAs(BookProjection.class).single();
|
||||
WebGraphQlHandler handler = graphQlSetup("bookById", fetcher).toWebGraphQlHandler();
|
||||
|
||||
Mono<WebOutput> outputMono = handler.handleRequest(input("{ bookById(id: 42) {name}}"));
|
||||
Mono<WebGraphQlResponse> responseMono = handler.handleRequest(request("{ bookById(id: 42) {name}}"));
|
||||
|
||||
Book actualBook = ResponseHelper.forResponse(outputMono).toEntity("bookById", Book.class);
|
||||
Book actualBook = ResponseHelper.forResponse(responseMono).toEntity("bookById", Book.class);
|
||||
assertThat(actualBook.getName()).isEqualTo("Hitchhiker's Guide to the Galaxy by Douglas Adams");
|
||||
}
|
||||
|
||||
@@ -111,9 +112,9 @@ class QueryByExampleDataFetcherReactiveMongoDbTests {
|
||||
DataFetcher<?> fetcher = QueryByExampleDataFetcher.builder(repository).projectAs(BookDto.class).single();
|
||||
WebGraphQlHandler handler = graphQlSetup("bookById", fetcher).toWebGraphQlHandler();
|
||||
|
||||
Mono<WebOutput> outputMono = handler.handleRequest(input("{ bookById(id: 42) {name}}"));
|
||||
Mono<WebGraphQlResponse> responseMono = handler.handleRequest(request("{ bookById(id: 42) {name}}"));
|
||||
|
||||
Book actualBook = ResponseHelper.forResponse(outputMono).toEntity("bookById", Book.class);
|
||||
Book actualBook = ResponseHelper.forResponse(responseMono).toEntity("bookById", Book.class);
|
||||
assertThat(actualBook.getName()).isEqualTo("The book is: Hitchhiker's Guide to the Galaxy");
|
||||
}
|
||||
|
||||
@@ -124,9 +125,10 @@ class QueryByExampleDataFetcherReactiveMongoDbTests {
|
||||
repository.saveAll(Flux.just(book1, book2)).blockLast();
|
||||
|
||||
Consumer<GraphQlSetup> tester = setup -> {
|
||||
Mono<WebOutput> outputMono = setup.toWebGraphQlHandler().handleRequest(input("{ books {name}}"));
|
||||
WebGraphQlRequest request = request("{ books {name}}");
|
||||
Mono<WebGraphQlResponse> responseMono = setup.toWebGraphQlHandler().handleRequest(request);
|
||||
|
||||
List<String> names = ResponseHelper.forResponse(outputMono).toList("books", Book.class)
|
||||
List<String> names = ResponseHelper.forResponse(responseMono).toList("books", Book.class)
|
||||
.stream().map(Book::getName).collect(Collectors.toList());
|
||||
|
||||
assertThat(names).containsExactlyInAnyOrder("Breaking Bad", "Hitchhiker's Guide to the Galaxy");
|
||||
@@ -156,8 +158,9 @@ class QueryByExampleDataFetcherReactiveMongoDbTests {
|
||||
return GraphQlSetup.schemaResource(BookSource.schema).runtimeWiring(configurer);
|
||||
}
|
||||
|
||||
private WebInput input(String query) {
|
||||
return new WebInput(URI.create("/"), new HttpHeaders(), Collections.singletonMap("query", query), "1", null);
|
||||
private WebGraphQlRequest request(String query) {
|
||||
return new WebGraphQlRequest(
|
||||
URI.create("/"), new HttpHeaders(), Collections.singletonMap("query", query), "1", null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -23,9 +23,9 @@ import reactor.core.publisher.Mono;
|
||||
public class ConsumeOneAndNeverCompleteInterceptor implements WebInterceptor {
|
||||
|
||||
@Override
|
||||
public Mono<WebOutput> intercept(WebInput webInput, WebInterceptorChain chain) {
|
||||
return chain.next(webInput).map((output) -> output.transform(builder -> {
|
||||
Object originalData = output.getData();
|
||||
public Mono<WebGraphQlResponse> intercept(WebGraphQlRequest request, WebInterceptorChain chain) {
|
||||
return chain.next(request).map(response -> response.transform(builder -> {
|
||||
Object originalData = response.getData();
|
||||
if (originalData instanceof Publisher) {
|
||||
Flux<?> updatedData = Flux.from((Publisher<?>) originalData).take(1).concatWith(Flux.never());
|
||||
builder.data(updatedData);
|
||||
|
||||
@@ -25,8 +25,8 @@ import graphql.schema.DataFetcher;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.graphql.ResponseHelper;
|
||||
import org.springframework.graphql.GraphQlSetup;
|
||||
import org.springframework.graphql.ResponseHelper;
|
||||
import org.springframework.graphql.TestThreadLocalAccessor;
|
||||
import org.springframework.graphql.execution.DataFetcherExceptionResolver;
|
||||
import org.springframework.graphql.execution.DataFetcherExceptionResolverAdapter;
|
||||
@@ -40,7 +40,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*/
|
||||
public class WebGraphQlHandlerTests {
|
||||
|
||||
private static final WebInput webInput = new WebInput(
|
||||
private static final WebGraphQlRequest webInput = new WebGraphQlRequest(
|
||||
URI.create("https://abc.org"), new HttpHeaders(), Collections.singletonMap("query", "{ greeting }"), "1", null);
|
||||
|
||||
|
||||
@@ -58,12 +58,12 @@ public class WebGraphQlHandlerTests {
|
||||
return Mono.delay(Duration.ofMillis(50)).map((aLong) -> "Hello " + name);
|
||||
});
|
||||
|
||||
Mono<WebOutput> outputMono =
|
||||
Mono<WebGraphQlResponse> responseMono =
|
||||
this.graphQlSetup.queryFetcher("greeting", dataFetcher).toWebGraphQlHandler()
|
||||
.handleRequest(webInput)
|
||||
.contextWrite((context) -> context.put("name", "007"));
|
||||
|
||||
String greeting = ResponseHelper.forResponse(outputMono).toEntity("greeting", String.class);
|
||||
String greeting = ResponseHelper.forResponse(responseMono).toEntity("greeting", String.class);
|
||||
assertThat(greeting).isEqualTo("Hello 007");
|
||||
}
|
||||
|
||||
@@ -76,13 +76,13 @@ public class WebGraphQlHandlerTests {
|
||||
.errorType(ErrorType.BAD_REQUEST)
|
||||
.build())));
|
||||
|
||||
Mono<WebOutput> outputMono = this.graphQlSetup.queryFetcher("greeting", this.errorDataFetcher)
|
||||
Mono<WebGraphQlResponse> responseMono = this.graphQlSetup.queryFetcher("greeting", this.errorDataFetcher)
|
||||
.exceptionResolver(exceptionResolver)
|
||||
.toWebGraphQlHandler()
|
||||
.handleRequest(webInput)
|
||||
.contextWrite((cxt) -> cxt.put("name", "007"));
|
||||
|
||||
ResponseHelper response = ResponseHelper.forResponse(outputMono);
|
||||
ResponseHelper response = ResponseHelper.forResponse(responseMono);
|
||||
assertThat(response.errorCount()).isEqualTo(1);
|
||||
assertThat(response.error(0).message()).isEqualTo("Resolved error: Invalid greeting, name=007");
|
||||
|
||||
@@ -97,14 +97,14 @@ public class WebGraphQlHandlerTests {
|
||||
TestThreadLocalAccessor<String> threadLocalAccessor = new TestThreadLocalAccessor<>(nameThreadLocal);
|
||||
try {
|
||||
|
||||
Mono<WebOutput> outputMono = this.graphQlSetup
|
||||
Mono<WebGraphQlResponse> responseMono = this.graphQlSetup
|
||||
.queryFetcher("greeting", env -> "Hello " + nameThreadLocal.get())
|
||||
.webInterceptor((input, next) -> Mono.delay(Duration.ofMillis(10)).flatMap((aLong) -> next.next(input)))
|
||||
.threadLocalAccessor(threadLocalAccessor)
|
||||
.toWebGraphQlHandler()
|
||||
.handleRequest(webInput);
|
||||
|
||||
String greeting = ResponseHelper.forResponse(outputMono).toEntity("greeting", String.class);
|
||||
String greeting = ResponseHelper.forResponse(responseMono).toEntity("greeting", String.class);
|
||||
assertThat(greeting).isEqualTo("Hello 007");
|
||||
}
|
||||
finally {
|
||||
@@ -124,14 +124,14 @@ public class WebGraphQlHandlerTests {
|
||||
.errorType(ErrorType.BAD_REQUEST).build());
|
||||
exceptionResolver.setThreadLocalContextAware(true);
|
||||
|
||||
Mono<WebOutput> outputMono = this.graphQlSetup.queryFetcher("greeting", this.errorDataFetcher)
|
||||
Mono<WebGraphQlResponse> responseMono = this.graphQlSetup.queryFetcher("greeting", this.errorDataFetcher)
|
||||
.exceptionResolver(exceptionResolver)
|
||||
.webInterceptor((input, next) -> Mono.delay(Duration.ofMillis(10)).flatMap((aLong) -> next.next(input)))
|
||||
.threadLocalAccessor(threadLocalAccessor)
|
||||
.toWebGraphQlHandler()
|
||||
.handleRequest(webInput);
|
||||
|
||||
ResponseHelper response = ResponseHelper.forResponse(outputMono);
|
||||
ResponseHelper response = ResponseHelper.forResponse(responseMono);
|
||||
assertThat(response.errorCount()).isEqualTo(1);
|
||||
assertThat(response.error(0).message()).isEqualTo("Resolved error: Invalid greeting, name=007");
|
||||
}
|
||||
|
||||
@@ -39,35 +39,35 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*/
|
||||
public class WebInterceptorTests {
|
||||
|
||||
private static final WebInput webInput = new WebInput(
|
||||
private static final WebGraphQlRequest webRequest = new WebGraphQlRequest(
|
||||
URI.create("http://abc.org"), new HttpHeaders(), Collections.singletonMap("query", "{ notUsed }"), "1", null);
|
||||
|
||||
@Test
|
||||
void interceptorOrder() {
|
||||
StringBuilder output = new StringBuilder();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
WebGraphQlHandler handler = WebGraphQlHandler.builder(this::emptyExecutionResult)
|
||||
.interceptors(Arrays.asList(
|
||||
new OrderInterceptor(1, output),
|
||||
new OrderInterceptor(2, output),
|
||||
new OrderInterceptor(3, output)))
|
||||
new OrderInterceptor(1, sb),
|
||||
new OrderInterceptor(2, sb),
|
||||
new OrderInterceptor(3, sb)))
|
||||
.build();
|
||||
|
||||
handler.handleRequest(webInput).block();
|
||||
assertThat(output.toString()).isEqualTo(":pre1:pre2:pre3:post3:post2:post1");
|
||||
handler.handleRequest(webRequest).block();
|
||||
assertThat(sb.toString()).isEqualTo(":pre1:pre2:pre3:post3:post2:post1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void responseHeader() {
|
||||
WebGraphQlHandler handler = WebGraphQlHandler.builder(this::emptyExecutionResult)
|
||||
.interceptor((input, next) -> next.next(input)
|
||||
.doOnNext(output -> {
|
||||
HttpHeaders httpHeaders = output.getResponseHeaders();
|
||||
.doOnNext(response -> {
|
||||
HttpHeaders httpHeaders = response.getResponseHeaders();
|
||||
httpHeaders.add("testHeader", "testValue");
|
||||
}))
|
||||
.build();
|
||||
|
||||
HttpHeaders headers = handler.handleRequest(webInput).block().getResponseHeaders();
|
||||
HttpHeaders headers = handler.handleRequest(webRequest).block().getResponseHeaders();
|
||||
|
||||
assertThat(headers.get("testHeader")).containsExactly("testValue");
|
||||
}
|
||||
@@ -81,13 +81,13 @@ public class WebInterceptorTests {
|
||||
actualName.set(request.toExecutionInput().getOperationName());
|
||||
return emptyExecutionResult(request);
|
||||
})
|
||||
.interceptor((webInput, next) -> {
|
||||
webInput.configureExecutionInput((input, builder) -> builder.operationName("testOp").build());
|
||||
return next.next(webInput);
|
||||
.interceptor((request, chain) -> {
|
||||
request.configureExecutionInput((input, builder) -> builder.operationName("testOp").build());
|
||||
return chain.next(request);
|
||||
})
|
||||
.build();
|
||||
|
||||
handler.handleRequest(webInput).block();
|
||||
handler.handleRequest(webRequest).block();
|
||||
|
||||
assertThat(actualName.get()).isEqualTo("testOp");
|
||||
}
|
||||
@@ -100,22 +100,22 @@ public class WebInterceptorTests {
|
||||
|
||||
private static class OrderInterceptor implements WebInterceptor {
|
||||
|
||||
private final StringBuilder output;
|
||||
private final StringBuilder sb;
|
||||
|
||||
private final int order;
|
||||
|
||||
OrderInterceptor(int order, StringBuilder output) {
|
||||
this.output = output;
|
||||
OrderInterceptor(int order, StringBuilder sb) {
|
||||
this.sb = sb;
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<WebOutput> intercept(WebInput input, WebInterceptorChain chain) {
|
||||
this.output.append(":pre").append(this.order);
|
||||
return chain.next(input)
|
||||
.map((output) -> {
|
||||
this.output.append(":post").append(this.order);
|
||||
return output;
|
||||
public Mono<WebGraphQlResponse> intercept(WebGraphQlRequest request, WebInterceptorChain chain) {
|
||||
this.sb.append(":pre").append(this.order);
|
||||
return chain.next(request)
|
||||
.map((response) -> {
|
||||
this.sb.append(":post").append(this.order);
|
||||
return response;
|
||||
})
|
||||
.subscribeOn(Schedulers.boundedElastic());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user