Extract GraphQlRequest interface
See gh-332
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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<String, Object> 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<String, Object> 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<String, Object> getVariables() {
|
||||
return this.variables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> toMap() {
|
||||
Map<String, Object> 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() : "");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<String, Object> 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<String, Object> 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<String, Object> getVariables() {
|
||||
return this.variables;
|
||||
}
|
||||
Map<String, Object> getVariables();
|
||||
|
||||
/**
|
||||
* Convert the request to a {@link Map} as defined in
|
||||
@@ -104,41 +64,6 @@ public class GraphQlRequest {
|
||||
* <tr><td>variables</td><td>{@link #getVariables() variables}</td></tr>
|
||||
* </table>
|
||||
*/
|
||||
public Map<String, Object> toMap() {
|
||||
Map<String, Object> 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<String, Object> toMap();
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
* <p>{@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;
|
||||
|
||||
|
||||
@@ -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<GraphQlRequest> 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) {
|
||||
|
||||
@@ -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<String, Object> responseMap) {
|
||||
return new DefaultClientGraphQlResponse(
|
||||
new GraphQlRequest("{test}"), GraphQlTransport.wrapResponseMap(responseMap),
|
||||
new DefaultGraphQlRequest("{test}"), GraphQlTransport.wrapResponseMap(responseMap),
|
||||
new Jackson2JsonEncoder(), new Jackson2JsonDecoder());
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<GraphQlRequest> requestCaptor = ArgumentCaptor.forClass(GraphQlRequest.class);
|
||||
private final ArgumentCaptor<GraphQlRequest> 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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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));
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user