Skip to content

Commit b516068

Browse files
committedJun 13, 2021
fix: 'Invalid Syntax : offending token '<EOF>'' when using Apollo persisted queries
1 parent d3f5151 commit b516068

10 files changed

+117
-34
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package graphql.kickstart.execution;
2+
3+
import com.fasterxml.jackson.core.JsonParser;
4+
import com.fasterxml.jackson.core.ObjectCodec;
5+
import com.fasterxml.jackson.databind.DeserializationContext;
6+
import com.fasterxml.jackson.databind.JsonDeserializer;
7+
import java.io.IOException;
8+
import java.util.Map;
9+
10+
public class ExtensionsDeserializer extends JsonDeserializer<Map<String, Object>> {
11+
12+
public static Map<String, Object> deserializeExtensionsObject(
13+
Object extensions, ObjectCodec codec) {
14+
return ObjectMapDeserializeHelper.deserializeObjectMapObject(extensions, codec, "extensions");
15+
}
16+
17+
@Override
18+
public Map<String, Object> deserialize(JsonParser p, DeserializationContext ctxt)
19+
throws IOException {
20+
return ExtensionsDeserializer.deserializeExtensionsObject(
21+
p.readValueAs(Object.class), p.getCodec());
22+
}
23+
}

‎graphql-java-kickstart/src/main/java/graphql/kickstart/execution/GraphQLObjectMapper.java

+6
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,12 @@ public Map<String, Object> deserializeVariables(String variables) {
174174
getJacksonMapper().readValue(variables, Object.class), getJacksonMapper());
175175
}
176176

177+
@SneakyThrows
178+
public Map<String, Object> deserializeExtensions(String extensions) {
179+
return ExtensionsDeserializer.deserializeExtensionsObject(
180+
getJacksonMapper().readValue(extensions, Object.class), getJacksonMapper());
181+
}
182+
177183
@SneakyThrows
178184
public Map<String, List<String>> deserializeMultipartMap(InputStream inputStream) {
179185
return getJacksonMapper().readValue(inputStream, MULTIPART_MAP_TYPE_REFERENCE);

‎graphql-java-kickstart/src/main/java/graphql/kickstart/execution/GraphQLRequest.java

+26-3
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,38 @@ public class GraphQLRequest {
1717
@JsonDeserialize(using = VariablesDeserializer.class)
1818
private Map<String, Object> variables = new HashMap<>();
1919

20+
@JsonDeserialize(using = ExtensionsDeserializer.class)
21+
private Map<String, Object> extensions = new HashMap<>();
22+
2023
private String operationName;
2124

2225
public GraphQLRequest() {}
2326

24-
public GraphQLRequest(String query, Map<String, Object> variables, String operationName) {
27+
public GraphQLRequest(
28+
String query,
29+
Map<String, Object> variables,
30+
Map<String, Object> extensions,
31+
String operationName) {
2532
this.query = query;
2633
this.operationName = operationName;
34+
if (extensions != null) {
35+
this.extensions = extensions;
36+
}
2737
if (variables != null) {
2838
this.variables = variables;
2939
}
3040
}
3141

3242
public static GraphQLRequest createIntrospectionRequest() {
3343
return new GraphQLRequest(
34-
IntrospectionQuery.INTROSPECTION_QUERY, new HashMap<>(), "IntrospectionQuery");
44+
IntrospectionQuery.INTROSPECTION_QUERY,
45+
new HashMap<>(),
46+
new HashMap<>(),
47+
"IntrospectionQuery");
3548
}
3649

3750
public static GraphQLRequest createQueryOnlyRequest(String query) {
38-
return new GraphQLRequest(query, new HashMap<>(), null);
51+
return new GraphQLRequest(query, new HashMap<>(), new HashMap<>(), null);
3952
}
4053

4154
public String getQuery() {
@@ -56,6 +69,16 @@ public void setVariables(Map<String, Object> variables) {
5669
}
5770
}
5871

72+
public Map<String, Object> getExtensions() {
73+
return extensions;
74+
}
75+
76+
public void setExtensions(Map<String, Object> extensions) {
77+
if (extensions != null) {
78+
this.extensions = extensions;
79+
}
80+
}
81+
5982
public String getOperationName() {
6083
return extractOperationName(query, operationName, null);
6184
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package graphql.kickstart.execution;
2+
3+
public class ObjectMapDeserializationException extends RuntimeException {
4+
5+
ObjectMapDeserializationException(String message) {
6+
super(message);
7+
}
8+
9+
ObjectMapDeserializationException(String message, Throwable cause) {
10+
super(message, cause);
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package graphql.kickstart.execution;
2+
3+
import com.fasterxml.jackson.core.ObjectCodec;
4+
import com.fasterxml.jackson.core.type.TypeReference;
5+
import java.io.IOException;
6+
import java.util.Map;
7+
8+
public class ObjectMapDeserializeHelper {
9+
10+
public static Map<String, Object> deserializeObjectMapObject(
11+
Object object, ObjectCodec codec, String fieldName) {
12+
if (object instanceof Map) {
13+
@SuppressWarnings("unchecked")
14+
Map<String, Object> genericObjectMap = (Map<String, Object>) object;
15+
return genericObjectMap;
16+
} else if (object instanceof String) {
17+
try {
18+
return codec.readValue(
19+
codec.getFactory().createParser((String) object),
20+
new TypeReference<Map<String, Object>>() {});
21+
} catch (IOException e) {
22+
throw new ObjectMapDeserializationException(
23+
String.format("Cannot deserialize field '%s'", fieldName), e);
24+
}
25+
} else {
26+
throw new ObjectMapDeserializationException(
27+
String.format("Field '%s' should be either an object or a string", fieldName));
28+
}
29+
}
30+
}

‎graphql-java-kickstart/src/main/java/graphql/kickstart/execution/VariablesDeserializationException.java

-12
This file was deleted.

‎graphql-java-kickstart/src/main/java/graphql/kickstart/execution/VariablesDeserializer.java

+1-17
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import com.fasterxml.jackson.core.JsonParser;
44
import com.fasterxml.jackson.core.ObjectCodec;
5-
import com.fasterxml.jackson.core.type.TypeReference;
65
import com.fasterxml.jackson.databind.DeserializationContext;
76
import com.fasterxml.jackson.databind.JsonDeserializer;
87
import java.io.IOException;
@@ -13,22 +12,7 @@ public class VariablesDeserializer extends JsonDeserializer<Map<String, Object>>
1312

1413
public static Map<String, Object> deserializeVariablesObject(
1514
Object variables, ObjectCodec codec) {
16-
if (variables instanceof Map) {
17-
@SuppressWarnings("unchecked")
18-
Map<String, Object> genericVariables = (Map<String, Object>) variables;
19-
return genericVariables;
20-
} else if (variables instanceof String) {
21-
try {
22-
return codec.readValue(
23-
codec.getFactory().createParser((String) variables),
24-
new TypeReference<Map<String, Object>>() {});
25-
} catch (IOException e) {
26-
throw new VariablesDeserializationException("Cannot deserialize variables", e);
27-
}
28-
} else {
29-
throw new VariablesDeserializationException(
30-
"Variables should be either an object or a string");
31-
}
15+
return ObjectMapDeserializeHelper.deserializeObjectMapObject(variables, codec, "variables");
3216
}
3317

3418
@Override

‎graphql-java-kickstart/src/main/java/graphql/kickstart/execution/input/GraphQLSingleInvocationInput.java

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ private ExecutionInput createExecutionInput(
4545
.context(context)
4646
.root(root)
4747
.variables(graphQLRequest.getVariables())
48+
.extensions(graphQLRequest.getExtensions())
4849
.dataLoaderRegistry(context.getDataLoaderRegistry())
4950
.executionId(ExecutionId.generate())
5051
.build();

‎graphql-java-servlet/src/main/java/graphql/kickstart/servlet/GraphQLGetInvocationInputParser.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@ public GraphQLInvocationInput getGraphQLInvocationInput(
3939

4040
if (isSingleQuery(query)) {
4141
Map<String, Object> variables = getVariables(request);
42+
Map<String, Object> extensions = getExtensions(request);
4243
String operationName = request.getParameter("operationName");
43-
GraphQLRequest graphqlRequest = new GraphQLRequest(query, variables, operationName);
44+
GraphQLRequest graphqlRequest =
45+
new GraphQLRequest(query, variables, extensions, operationName);
4446
return invocationInputFactory.createReadOnly(graphqlRequest, request, response);
4547
}
4648

@@ -61,4 +63,11 @@ private Map<String, Object> getVariables(HttpServletRequest request) {
6163
.map(HashMap::new)
6264
.orElseGet(HashMap::new);
6365
}
66+
67+
private Map<String, Object> getExtensions(HttpServletRequest request) {
68+
return Optional.ofNullable(request.getParameter("extensions"))
69+
.map(graphQLObjectMapper::deserializeExtensions)
70+
.map(HashMap::new)
71+
.orElseGet(HashMap::new);
72+
}
6473
}

‎graphql-java-servlet/src/main/java/graphql/kickstart/servlet/GraphQLMultipartInvocationInputParser.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -150,13 +150,20 @@ private GraphQLRequest buildRequestFromQuery(
150150
graphQLObjectMapper.deserializeVariables(read(variablesItem.get().getInputStream()));
151151
}
152152

153+
Map<String, Object> extensions = null;
154+
final Optional<Part> extensionsItem = getPart(parts, "extensions");
155+
if (extensionsItem.isPresent()) {
156+
extensions =
157+
graphQLObjectMapper.deserializeExtensions(read(extensionsItem.get().getInputStream()));
158+
}
159+
153160
String operationName = null;
154161
final Optional<Part> operationNameItem = getPart(parts, "operationName");
155162
if (operationNameItem.isPresent()) {
156163
operationName = read(operationNameItem.get().getInputStream()).trim();
157164
}
158165

159-
return new GraphQLRequest(query, variables, operationName);
166+
return new GraphQLRequest(query, variables, extensions, operationName);
160167
}
161168

162169
private String read(InputStream inputStream) throws IOException {

0 commit comments

Comments
 (0)
Please sign in to comment.