diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultGraphQlTester.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultGraphQlTester.java index db7356fc..3b64c07e 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultGraphQlTester.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultGraphQlTester.java @@ -34,6 +34,7 @@ import com.jayway.jsonpath.TypeRef; import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.ResolvableType; +import org.springframework.graphql.DefaultGraphQlRequest; import org.springframework.graphql.GraphQlRequest; import org.springframework.graphql.GraphQlResponse; import org.springframework.graphql.GraphQlResponseError; @@ -179,7 +180,7 @@ final class DefaultGraphQlTester implements GraphQlTester { } private GraphQlRequest request() { - return new GraphQlRequest(this.document, this.operationName, this.variables); + return new DefaultGraphQlRequest(this.document, this.operationName, this.variables); } private DefaultResponse mapResponse(GraphQlResponse response, GraphQlRequest request) { diff --git a/spring-graphql/src/main/java/org/springframework/graphql/DefaultGraphQlRequest.java b/spring-graphql/src/main/java/org/springframework/graphql/DefaultGraphQlRequest.java new file mode 100644 index 00000000..bec021a4 --- /dev/null +++ b/spring-graphql/src/main/java/org/springframework/graphql/DefaultGraphQlRequest.java @@ -0,0 +1,123 @@ +/* + * Copyright 2002-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.graphql; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +/** + * Default implementation of {@link GraphQlRequest}. + * + * @author Rossen Stoyanchev + * @since 1.0.0 + */ +public class DefaultGraphQlRequest implements GraphQlRequest { + + private final String document; + + @Nullable + private final String operationName; + + private final Map variables; + + + /** + * Create a request. + * @param document textual representation of the operation(s) + */ + public DefaultGraphQlRequest(String document) { + this(document, null, null); + } + + /** + * Create a request with a complete set of inputs. + * @param document textual representation of the operation(s) + * @param operationName optionally, the name of the operation to execute + * @param variables variables by which the operation is parameterized + */ + public DefaultGraphQlRequest( + String document, @Nullable String operationName, @Nullable Map variables) { + + Assert.notNull(document, "'document' is required"); + this.document = document; + this.operationName = operationName; + this.variables = (variables != null ? variables : Collections.emptyMap()); + } + + + @Override + public String getDocument() { + return this.document; + } + + @Override + @Nullable + public String getOperationName() { + return this.operationName; + } + + @Override + public Map getVariables() { + return this.variables; + } + + @Override + public Map toMap() { + Map map = new LinkedHashMap<>(3); + map.put("query", getDocument()); + if (getOperationName() != null) { + map.put("operationName", getOperationName()); + } + if (!CollectionUtils.isEmpty(getVariables())) { + map.put("variables", new LinkedHashMap<>(getVariables())); + } + return map; + } + + + @Override + public boolean equals(Object o) { + if (! (o instanceof DefaultGraphQlRequest)) { + return false; + } + DefaultGraphQlRequest other = (DefaultGraphQlRequest) o; + return (getDocument().equals(other.getDocument()) && + ObjectUtils.nullSafeEquals(getOperationName(), other.getOperationName()) && + ObjectUtils.nullSafeEquals(getVariables(), other.getVariables())); + } + + @Override + public int hashCode() { + return this.document.hashCode() + + 31 * ObjectUtils.nullSafeHashCode(this.operationName) + + 31 * this.variables.hashCode(); + } + + @Override + public String toString() { + return "document='" + getDocument() + "'" + + ((getOperationName() != null) ? ", operationName='" + getOperationName() + "'" : "") + + (!CollectionUtils.isEmpty(getVariables()) ? ", variables=" + getVariables() : ""); + } + +} diff --git a/spring-graphql/src/main/java/org/springframework/graphql/GraphQlRequest.java b/spring-graphql/src/main/java/org/springframework/graphql/GraphQlRequest.java index 80eaeef0..a5938b82 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/GraphQlRequest.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/GraphQlRequest.java @@ -16,14 +16,10 @@ package org.springframework.graphql; -import java.util.Collections; -import java.util.LinkedHashMap; import java.util.Map; import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.CollectionUtils; -import org.springframework.util.ObjectUtils; + /** * Represents a GraphQL request with the inputs to pass to a GraphQL service @@ -36,62 +32,26 @@ import org.springframework.util.ObjectUtils; * @author Rossen Stoyanchev * @since 1.0.0 */ -public class GraphQlRequest { - - private final String document; - - @Nullable - private final String operationName; - - private final Map variables; - - - /** - * Create a request. - * @param document textual representation of the operation(s) - */ - public GraphQlRequest(String document) { - this(document, null, null); - } - - /** - * Create a request with a complete set of inputs. - * @param document textual representation of the operation(s) - * @param operationName optionally, the name of the operation to execute - * @param variables variables by which the operation is parameterized - */ - public GraphQlRequest(String document, @Nullable String operationName, @Nullable Map variables) { - Assert.notNull(document, "'document' is required"); - this.document = document; - this.operationName = operationName; - this.variables = (variables != null ? variables : Collections.emptyMap()); - } - +public interface GraphQlRequest { /** * Return the GraphQL document which is the textual representation of an * operation (or operations) to perform, including any selection sets and * fragments. */ - public String getDocument() { - return this.document; - } + String getDocument(); /** * Return the name of the operation in the {@link #getDocument() document} * to execute, if the document contains multiple operations. */ @Nullable - public String getOperationName() { - return this.operationName; - } + String getOperationName(); /** * Return values for variable defined by the operation. */ - public Map getVariables() { - return this.variables; - } + Map getVariables(); /** * Convert the request to a {@link Map} as defined in @@ -104,41 +64,6 @@ public class GraphQlRequest { * variables{@link #getVariables() variables} * */ - public Map toMap() { - Map map = new LinkedHashMap<>(3); - map.put("query", getDocument()); - if (getOperationName() != null) { - map.put("operationName", getOperationName()); - } - if (!CollectionUtils.isEmpty(getVariables())) { - map.put("variables", new LinkedHashMap<>(getVariables())); - } - return map; - } - - @Override - public boolean equals(Object o) { - if (! (o instanceof GraphQlRequest)) { - return false; - } - GraphQlRequest other = (GraphQlRequest) o; - return (getDocument().equals(other.getDocument()) && - ObjectUtils.nullSafeEquals(getOperationName(), other.getOperationName()) && - ObjectUtils.nullSafeEquals(getVariables(), other.getVariables())); - } - - @Override - public int hashCode() { - return this.document.hashCode() + - 31 * ObjectUtils.nullSafeHashCode(this.operationName) + - 31 * this.variables.hashCode(); - } - - @Override - public String toString() { - return "document='" + getDocument() + "'" + - ((getOperationName() != null) ? ", operationName='" + getOperationName() + "'" : "") + - (!CollectionUtils.isEmpty(getVariables()) ? ", variables=" + getVariables() : ""); - } + Map toMap(); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/RequestInput.java b/spring-graphql/src/main/java/org/springframework/graphql/RequestInput.java index 657541bf..c53aae7b 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/RequestInput.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/RequestInput.java @@ -29,10 +29,9 @@ import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** - * Extension of {@link GraphQlRequest} for server side handling, adding the - * transport (e.g. HTTP or WebSocket handler) assigned {@link #getId() id} and - * {@link #getLocale() locale} in the addition to the {@link GraphQlRequest} - * inputs. + * {@link GraphQlRequest} for server side handling, adding the transport (e.g. HTTP + * or WebSocket handler) assigned {@link #getId() id} and {@link #getLocale() + * locale} in the addition to the {@code GraphQlRequest} inputs. * *

{@code RequestInput} supports the initialization of {@link ExecutionInput} * that is passed to {@link graphql.GraphQL}. You can customize that via @@ -42,7 +41,7 @@ import org.springframework.util.Assert; * @author Brian Clozel * @since 1.0.0 */ -public class RequestInput extends GraphQlRequest { +public class RequestInput extends DefaultGraphQlRequest { private final String id; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultGraphQlClient.java b/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultGraphQlClient.java index 59255e01..02fbb826 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultGraphQlClient.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultGraphQlClient.java @@ -27,6 +27,7 @@ import reactor.core.publisher.Mono; import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.codec.Decoder; import org.springframework.core.codec.Encoder; +import org.springframework.graphql.DefaultGraphQlRequest; import org.springframework.graphql.GraphQlRequest; import org.springframework.graphql.GraphQlResponse; import org.springframework.graphql.support.DocumentSource; @@ -176,7 +177,7 @@ final class DefaultGraphQlClient implements GraphQlClient { private Mono initRequest() { return this.documentMono.map(document -> - new GraphQlRequest(document, this.operationName, this.variables)); + new DefaultGraphQlRequest(document, this.operationName, this.variables)); } private DefaultClientGraphQlResponse initResponse(GraphQlRequest request, GraphQlResponse response) { diff --git a/spring-graphql/src/test/java/org/springframework/graphql/client/DefaultGraphQlClientResponseTests.java b/spring-graphql/src/test/java/org/springframework/graphql/client/DefaultGraphQlClientResponseTests.java index 1f0fe2ed..982b3319 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/client/DefaultGraphQlClientResponseTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/client/DefaultGraphQlClientResponseTests.java @@ -28,7 +28,7 @@ import graphql.execution.ResultPath; import org.junit.jupiter.api.Test; import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper; -import org.springframework.graphql.GraphQlRequest; +import org.springframework.graphql.DefaultGraphQlRequest; import org.springframework.graphql.GraphQlResponseError; import org.springframework.http.codec.json.Jackson2JsonDecoder; import org.springframework.http.codec.json.Jackson2JsonEncoder; @@ -158,7 +158,7 @@ public class DefaultGraphQlClientResponseTests { private ClientGraphQlResponse creatResponse(Map responseMap) { return new DefaultClientGraphQlResponse( - new GraphQlRequest("{test}"), GraphQlTransport.wrapResponseMap(responseMap), + new DefaultGraphQlRequest("{test}"), GraphQlTransport.wrapResponseMap(responseMap), new Jackson2JsonEncoder(), new Jackson2JsonDecoder()); } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/client/GraphQlClientBuilderTests.java b/spring-graphql/src/test/java/org/springframework/graphql/client/GraphQlClientBuilderTests.java index fc1e6c55..a8365984 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/client/GraphQlClientBuilderTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/client/GraphQlClientBuilderTests.java @@ -19,7 +19,6 @@ package org.springframework.graphql.client; import org.junit.jupiter.api.Test; import reactor.core.publisher.Mono; -import org.springframework.graphql.GraphQlRequest; import org.springframework.graphql.support.DocumentSource; import static org.assertj.core.api.Assertions.assertThat; 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 a4c092de..39b2c885 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 @@ -28,6 +28,7 @@ import graphql.GraphQLError; import org.mockito.ArgumentCaptor; import reactor.core.publisher.Mono; +import org.springframework.graphql.DefaultGraphQlRequest; import org.springframework.graphql.GraphQlRequest; import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; @@ -49,7 +50,7 @@ public class GraphQlClientTestSupport { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); - private final ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(GraphQlRequest.class); + private final ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(DefaultGraphQlRequest.class); private final GraphQlTransport transport = mock(GraphQlTransport.class); @@ -72,15 +73,15 @@ public class GraphQlClientTestSupport { protected void initDataResponse(String document, String responseData) { - initResponse(new GraphQlRequest(document), responseData); + initResponse(new DefaultGraphQlRequest(document), responseData); } protected void initErrorResponse(String document, GraphQLError... errors) { - initResponse(new GraphQlRequest(document), null, errors); + initResponse(new DefaultGraphQlRequest(document), null, errors); } protected void initResponse(String document, String responseData, GraphQLError... errors) { - initResponse(new GraphQlRequest(document), responseData, errors); + initResponse(new DefaultGraphQlRequest(document), responseData, errors); } protected void initResponse(GraphQlRequest request, @Nullable String responseData, GraphQLError... errors) { diff --git a/spring-graphql/src/test/java/org/springframework/graphql/client/GraphQlClientTests.java b/spring-graphql/src/test/java/org/springframework/graphql/client/GraphQlClientTests.java index 71a65075..7f9daabd 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/client/GraphQlClientTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/client/GraphQlClientTests.java @@ -30,6 +30,7 @@ import graphql.validation.ValidationErrorType; import org.junit.jupiter.api.Test; import org.springframework.core.ParameterizedTypeReference; +import org.springframework.graphql.DefaultGraphQlRequest; import org.springframework.graphql.GraphQlRequest; import static org.assertj.core.api.Assertions.assertThat; @@ -100,7 +101,7 @@ public class GraphQlClientTests extends GraphQlClientTestSupport { vars.put("foo", "bar"); vars.put("keyOnly", null); - GraphQlRequest request = new GraphQlRequest("mockRequest1", "HeroNameAndFriends", vars); + GraphQlRequest request = new DefaultGraphQlRequest("mockRequest1", "HeroNameAndFriends", vars); initResponse(request, "{\"hero\": {\"name\":\"R2-D2\"}}"); MovieCharacter character = graphQlClient().document(document) 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 d2efbab2..92262164 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 @@ -31,6 +31,7 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +import org.springframework.graphql.DefaultGraphQlRequest; import org.springframework.graphql.GraphQlRequest; import org.springframework.graphql.GraphQlResponse; import org.springframework.graphql.GraphQlResponseError; @@ -175,7 +176,7 @@ public class MockWebSocketGraphQlTransportTests { TestWebSocketClient client = new TestWebSocketClient(new PingResponseHandler(this.response1)); WebSocketGraphQlTransport transport = createTransport(client); - StepVerifier.create(transport.execute(new GraphQlRequest("{Query1}"))) + StepVerifier.create(transport.execute(new DefaultGraphQlRequest("{Query1}"))) .expectNext(this.response1) .expectComplete() .verify(TIMEOUT); @@ -183,7 +184,7 @@ public class MockWebSocketGraphQlTransportTests { assertActualClientMessages(client.getConnection(0), GraphQlMessage.connectionInit(null), GraphQlMessage.pong(null), - GraphQlMessage.subscribe("1", new GraphQlRequest("{Query1}"))); + GraphQlMessage.subscribe("1", new DefaultGraphQlRequest("{Query1}"))); } @Test @@ -303,7 +304,7 @@ public class MockWebSocketGraphQlTransportTests { String expectedMessage = "disconnected with CloseStatus[code=4400, reason=Invalid message]"; - StepVerifier.create(transport.execute(new GraphQlRequest("{Query1}"))) + StepVerifier.create(transport.execute(new DefaultGraphQlRequest("{Query1}"))) .expectErrorSatisfies(ex -> assertThat(ex).hasMessageEndingWith(expectedMessage)) .verify(TIMEOUT); } @@ -381,7 +382,7 @@ public class MockWebSocketGraphQlTransportTests { GraphQlMessage outputMessage = (inputMessage.resolvedType() == GraphQlMessageType.CONNECTION_INIT ? GraphQlMessage.connectionAck(null) : - GraphQlMessage.subscribe(id, new GraphQlRequest(""))); + GraphQlMessage.subscribe(id, new DefaultGraphQlRequest(""))); return Flux.just(this.codecDelegate.encode(session, outputMessage)); }));