From 96135183f5ca18e5d5db3e0988ff054b9a3d290e Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Thu, 17 Mar 2022 19:56:31 +0000 Subject: [PATCH] Refactor MapGraphQlResponse MapGraphQlResponse is a simple wrapper around the response map exposing it as GraphQlResponse. It is now package private and made accessible through a static factory method on GraphQlTransport. See gh-10 --- .../test/tester/WebTestClientTransport.java | 3 +- .../client/DefaultClientGraphQlResponse.java | 1 - .../graphql/client/GraphQlTransport.java | 10 ++++++ .../graphql/client/HttpGraphQlTransport.java | 3 +- .../{support => client}/MapGraphQlError.java | 4 +-- .../MapGraphQlResponse.java | 34 +++---------------- .../client/WebSocketGraphQlTransport.java | 5 ++- .../client/GraphQlClientTestSupport.java | 3 +- .../MapGraphQlResponseTests.java | 18 +++++----- .../MockWebSocketGraphQlTransportTests.java | 7 ++-- 10 files changed, 34 insertions(+), 54 deletions(-) rename spring-graphql/src/main/java/org/springframework/graphql/{support => client}/MapGraphQlError.java (96%) rename spring-graphql/src/main/java/org/springframework/graphql/{support => client}/MapGraphQlResponse.java (85%) rename spring-graphql/src/test/java/org/springframework/graphql/{support => client}/MapGraphQlResponseTests.java (88%) diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/WebTestClientTransport.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/WebTestClientTransport.java index 6e188e76..03d7a4ad 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/WebTestClientTransport.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/WebTestClientTransport.java @@ -26,7 +26,6 @@ import org.springframework.core.ParameterizedTypeReference; import org.springframework.graphql.GraphQlRequest; import org.springframework.graphql.GraphQlResponse; import org.springframework.graphql.client.GraphQlTransport; -import org.springframework.graphql.support.MapGraphQlResponse; import org.springframework.http.MediaType; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.util.Assert; @@ -67,7 +66,7 @@ final class WebTestClientTransport implements GraphQlTransport { .getResponseBody(); responseMap = (responseMap != null ? responseMap : Collections.emptyMap()); - GraphQlResponse response = MapGraphQlResponse.forResponse(responseMap); + GraphQlResponse response = GraphQlTransport.wrapResponseMap(responseMap); return Mono.just(response); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultClientGraphQlResponse.java b/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultClientGraphQlResponse.java index 2acea8c4..c97403c4 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultClientGraphQlResponse.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultClientGraphQlResponse.java @@ -31,7 +31,6 @@ import org.springframework.core.io.buffer.DataBufferFactory; import org.springframework.core.io.buffer.DefaultDataBufferFactory; import org.springframework.graphql.GraphQlRequest; import org.springframework.graphql.GraphQlResponse; -import org.springframework.graphql.support.MapGraphQlResponse; import org.springframework.lang.Nullable; import org.springframework.util.MimeType; import org.springframework.util.MimeTypeUtils; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/GraphQlTransport.java b/spring-graphql/src/main/java/org/springframework/graphql/client/GraphQlTransport.java index fe053ea5..878b7a0a 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/GraphQlTransport.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/GraphQlTransport.java @@ -16,6 +16,8 @@ package org.springframework.graphql.client; +import java.util.Map; + import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -57,4 +59,12 @@ public interface GraphQlTransport { */ Flux executeSubscription(GraphQlRequest request); + + /** + * Wrap the given response map and expose it as a {@link GraphQlResponse}. + */ + static GraphQlResponse wrapResponseMap(Map map) { + return new MapGraphQlResponse(map); + } + } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/HttpGraphQlTransport.java b/spring-graphql/src/main/java/org/springframework/graphql/client/HttpGraphQlTransport.java index c4ff834a..f4f3e11b 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/HttpGraphQlTransport.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/HttpGraphQlTransport.java @@ -24,7 +24,6 @@ import reactor.core.publisher.Mono; import org.springframework.core.ParameterizedTypeReference; import org.springframework.graphql.GraphQlRequest; import org.springframework.graphql.GraphQlResponse; -import org.springframework.graphql.support.MapGraphQlResponse; import org.springframework.http.MediaType; import org.springframework.util.Assert; import org.springframework.web.reactive.function.client.WebClient; @@ -61,7 +60,7 @@ final class HttpGraphQlTransport implements GraphQlTransport { .bodyValue(request.toMap()) .retrieve() .bodyToMono(MAP_TYPE) - .map(MapGraphQlResponse::forResponse); + .map(GraphQlTransport::wrapResponseMap); } @Override diff --git a/spring-graphql/src/main/java/org/springframework/graphql/support/MapGraphQlError.java b/spring-graphql/src/main/java/org/springframework/graphql/client/MapGraphQlError.java similarity index 96% rename from spring-graphql/src/main/java/org/springframework/graphql/support/MapGraphQlError.java rename to spring-graphql/src/main/java/org/springframework/graphql/client/MapGraphQlError.java index 475007f3..75617eeb 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/support/MapGraphQlError.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/MapGraphQlError.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.graphql.support; +package org.springframework.graphql.client; import java.util.Collections; import java.util.List; @@ -31,7 +31,7 @@ import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** - * Implementation of {@link GraphQLError} backed by a {@link Map}. + * {@link GraphQLError} that wraps a deserialized the GraphQL response map. * * @author Rossen Stoyanchev * @since 1.0.0 diff --git a/spring-graphql/src/main/java/org/springframework/graphql/support/MapGraphQlResponse.java b/spring-graphql/src/main/java/org/springframework/graphql/client/MapGraphQlResponse.java similarity index 85% rename from spring-graphql/src/main/java/org/springframework/graphql/support/MapGraphQlResponse.java rename to spring-graphql/src/main/java/org/springframework/graphql/client/MapGraphQlResponse.java index 40d4bd91..9eb17db9 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/support/MapGraphQlResponse.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/MapGraphQlResponse.java @@ -14,14 +14,13 @@ * limitations under the License. */ -package org.springframework.graphql.support; +package org.springframework.graphql.client; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; -import graphql.ExecutionResult; import graphql.GraphQLError; import org.springframework.graphql.GraphQlResponse; @@ -31,12 +30,12 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; /** - * {@link GraphQlResponse} for client use that wraps the GraphQL response map. + * {@link GraphQlResponse} that wraps a deserialized the GraphQL response map. * * @author Rossen Stoyanchev * @since 1.0.0 */ -public class MapGraphQlResponse implements GraphQlResponse { +class MapGraphQlResponse implements GraphQlResponse { /** * Returned from {@link #getFieldValue(List)} to indicate a value does not exist. @@ -49,7 +48,7 @@ public class MapGraphQlResponse implements GraphQlResponse { private final List errors; - protected MapGraphQlResponse(Map responseMap) { + MapGraphQlResponse(Map responseMap) { Assert.notNull(responseMap, "'responseMap' is required"); this.responseMap = responseMap; this.errors = wrapErrors(responseMap); @@ -218,29 +217,4 @@ public class MapGraphQlResponse implements GraphQlResponse { return this.responseMap.toString(); } - - /** - * Create an instance from an {@code ExecutionResult} serialized to map via - * {@link ExecutionResult#toSpecification()}. - */ - public static MapGraphQlResponse forResponse(Map map) { - return new MapGraphQlResponse(map); - } - - /** - * Create an {@code ExecutionResult} with a "data" key that returns the - * given map. - */ - public static MapGraphQlResponse forDataOnly(@Nullable Map map) { - return new MapGraphQlResponse(Collections.singletonMap("data", map)); - } - - /** - * Create an {@code ExecutionResult} with an "errors" key that returns the - * given serialized errors. - */ - public static MapGraphQlResponse forErrorsOnly(List> errors) { - return new MapGraphQlResponse(Collections.singletonMap("errors", errors)); - } - } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/WebSocketGraphQlTransport.java b/spring-graphql/src/main/java/org/springframework/graphql/client/WebSocketGraphQlTransport.java index 0e0de7ff..84c2b55d 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/WebSocketGraphQlTransport.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/WebSocketGraphQlTransport.java @@ -34,7 +34,6 @@ import reactor.core.publisher.Sinks; import org.springframework.graphql.GraphQlRequest; import org.springframework.graphql.GraphQlResponse; -import org.springframework.graphql.support.MapGraphQlResponse; import org.springframework.graphql.web.support.GraphQlMessage; import org.springframework.graphql.web.support.GraphQlMessageType; import org.springframework.http.HttpHeaders; @@ -477,7 +476,7 @@ final class WebSocketGraphQlTransport implements GraphQlTransport { } Map responseMap = message.getPayload(); - GraphQlResponse graphQlResponse = MapGraphQlResponse.forResponse(responseMap); + GraphQlResponse graphQlResponse = GraphQlTransport.wrapResponseMap(responseMap); Sinks.EmitResult emitResult = (responseState != null ? responseState.sink().tryEmitValue(graphQlResponse) : @@ -508,7 +507,7 @@ final class WebSocketGraphQlTransport implements GraphQlTransport { } List> errorList = message.getPayload(); - GraphQlResponse response = MapGraphQlResponse.forErrorsOnly(errorList); + GraphQlResponse response = GraphQlTransport.wrapResponseMap(Collections.singletonMap("errors", errorList)); Sinks.EmitResult emitResult; if (responseState != null) { diff --git a/spring-graphql/src/test/java/org/springframework/graphql/client/GraphQlClientTestSupport.java b/spring-graphql/src/test/java/org/springframework/graphql/client/GraphQlClientTestSupport.java index 1761fa0b..a4c092de 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/client/GraphQlClientTestSupport.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/client/GraphQlClientTestSupport.java @@ -29,7 +29,6 @@ import org.mockito.ArgumentCaptor; import reactor.core.publisher.Mono; import org.springframework.graphql.GraphQlRequest; -import org.springframework.graphql.support.MapGraphQlResponse; import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; @@ -96,7 +95,7 @@ public class GraphQlClientTestSupport { Map responseMap = executionResult.toSpecification(); when(this.transport.execute(eq(request))) - .thenReturn(Mono.just(MapGraphQlResponse.forResponse(responseMap))); + .thenReturn(Mono.just(GraphQlTransport.wrapResponseMap(responseMap))); } @SuppressWarnings("unchecked") diff --git a/spring-graphql/src/test/java/org/springframework/graphql/support/MapGraphQlResponseTests.java b/spring-graphql/src/test/java/org/springframework/graphql/client/MapGraphQlResponseTests.java similarity index 88% rename from spring-graphql/src/test/java/org/springframework/graphql/support/MapGraphQlResponseTests.java rename to spring-graphql/src/test/java/org/springframework/graphql/client/MapGraphQlResponseTests.java index 49662f31..16b36223 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/support/MapGraphQlResponseTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/client/MapGraphQlResponseTests.java @@ -14,9 +14,10 @@ * limitations under the License. */ -package org.springframework.graphql.support; +package org.springframework.graphql.client; import java.io.IOException; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -32,7 +33,6 @@ import org.springframework.lang.Nullable; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.springframework.graphql.support.MapGraphQlResponse.NO_VALUE; /** @@ -81,12 +81,12 @@ public class MapGraphQlResponseTests { // null "data" testFieldValue("", "null", null); - testFieldValue("me", "null", NO_VALUE); + testFieldValue("me", "null", MapGraphQlResponse.NO_VALUE); // no such key or index - testFieldValue("me", "{}", NO_VALUE); // "data" not null but no such key - testFieldValue("me.friends", "{\"me\":{}}", NO_VALUE); - testFieldValue("me.friends[0]", "{\"me\": {\"friends\": []}}", NO_VALUE); + testFieldValue("me", "{}", MapGraphQlResponse.NO_VALUE); // "data" not null but no such key + testFieldValue("me.friends", "{\"me\":{}}", MapGraphQlResponse.NO_VALUE); + testFieldValue("me.friends[0]", "{\"me\": {\"friends\": []}}", MapGraphQlResponse.NO_VALUE); // nest within map or list testFieldValue("me.name", "{\"me\":{\"name\":\"Luke\"}}", "Luke"); @@ -97,7 +97,7 @@ public class MapGraphQlResponseTests { private static void testFieldValue(String path, String json, @Nullable Object expected) throws IOException { List parsedPath = MapGraphQlResponse.parseFieldPath(path); Map map = mapper.readValue(json, Map.class); - MapGraphQlResponse response = MapGraphQlResponse.forDataOnly(map); + MapGraphQlResponse response = new MapGraphQlResponse(Collections.singletonMap("data", map)); Object value = response.getFieldValue(parsedPath); if (expected != null) { assertThat(value).isEqualTo(expected); @@ -119,7 +119,7 @@ public class MapGraphQlResponseTests { private static void testFieldValueInvalidPath(String path, String json) throws IOException { List parsedPath = MapGraphQlResponse.parseFieldPath(path); Map map = mapper.readValue(json, Map.class); - MapGraphQlResponse response = MapGraphQlResponse.forDataOnly(map); + MapGraphQlResponse response = new MapGraphQlResponse(Collections.singletonMap("data", map)); assertThatIllegalArgumentException().isThrownBy(() -> response.getFieldValue(parsedPath)) .withMessage("Invalid path " + parsedPath + ", data: " + map); @@ -139,7 +139,7 @@ public class MapGraphQlResponseTests { Stream.of(error0, error1, error2, error3) .map(GraphQLError::toSpecification).collect(Collectors.toList()); - MapGraphQlResponse response = MapGraphQlResponse.forErrorsOnly(errorList); + MapGraphQlResponse response = new MapGraphQlResponse(Collections.singletonMap("errors", errorList)); List errors = response.getFieldErrors(path); assertThat(errors).containsExactly(error1, error2, error3); diff --git a/spring-graphql/src/test/java/org/springframework/graphql/client/MockWebSocketGraphQlTransportTests.java b/spring-graphql/src/test/java/org/springframework/graphql/client/MockWebSocketGraphQlTransportTests.java index 85be9839..ea41b5d7 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/client/MockWebSocketGraphQlTransportTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/client/MockWebSocketGraphQlTransportTests.java @@ -34,7 +34,6 @@ import reactor.test.StepVerifier; import org.springframework.graphql.GraphQlRequest; import org.springframework.graphql.GraphQlResponse; -import org.springframework.graphql.support.MapGraphQlResponse; import org.springframework.graphql.web.TestWebSocketClient; import org.springframework.graphql.web.TestWebSocketConnection; import org.springframework.graphql.web.support.GraphQlMessage; @@ -70,9 +69,11 @@ public class MockWebSocketGraphQlTransportTests { private final WebSocketGraphQlTransport transport = createTransport(this.webSocketClient); - private final GraphQlResponse response1 = MapGraphQlResponse.forDataOnly(Collections.singletonMap("key1", "value1")); + private final GraphQlResponse response1 = GraphQlTransport.wrapResponseMap( + Collections.singletonMap("data", Collections.singletonMap("key1", "value1"))); - private final GraphQlResponse response2 = MapGraphQlResponse.forDataOnly(Collections.singletonMap("key2", "value2")); + private final GraphQlResponse response2 = GraphQlTransport.wrapResponseMap( + Collections.singletonMap("data", Collections.singletonMap("key2", "value2"))); @Test