Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 'Invalid Syntax : offending token '<EOF>'' when using Apollo persisted queries #356

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package graphql.kickstart.execution;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import java.util.Map;

public class ExtensionsDeserializer extends JsonDeserializer<Map<String, Object>> {

public static Map<String, Object> deserializeExtensionsObject(
Object extensions, ObjectCodec codec) {
return ObjectMapDeserializeHelper.deserializeObjectMapObject(extensions, codec, "extensions");
}

@Override
public Map<String, Object> deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException {
return ExtensionsDeserializer.deserializeExtensionsObject(
p.readValueAs(Object.class), p.getCodec());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,12 @@ public Map<String, Object> deserializeVariables(String variables) {
getJacksonMapper().readValue(variables, Object.class), getJacksonMapper());
}

@SneakyThrows
public Map<String, Object> deserializeExtensions(String extensions) {
return ExtensionsDeserializer.deserializeExtensionsObject(
getJacksonMapper().readValue(extensions, Object.class), getJacksonMapper());
}

@SneakyThrows
public Map<String, List<String>> deserializeMultipartMap(InputStream inputStream) {
return getJacksonMapper().readValue(inputStream, MULTIPART_MAP_TYPE_REFERENCE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,38 @@ public class GraphQLRequest {
@JsonDeserialize(using = VariablesDeserializer.class)
private Map<String, Object> variables = new HashMap<>();

@JsonDeserialize(using = ExtensionsDeserializer.class)
private Map<String, Object> extensions = new HashMap<>();

private String operationName;

public GraphQLRequest() {}

public GraphQLRequest(String query, Map<String, Object> variables, String operationName) {
public GraphQLRequest(
String query,
Map<String, Object> variables,
Map<String, Object> extensions,
String operationName) {
this.query = query;
this.operationName = operationName;
if (extensions != null) {
this.extensions = extensions;
}
if (variables != null) {
this.variables = variables;
}
}

public static GraphQLRequest createIntrospectionRequest() {
return new GraphQLRequest(
IntrospectionQuery.INTROSPECTION_QUERY, new HashMap<>(), "IntrospectionQuery");
IntrospectionQuery.INTROSPECTION_QUERY,
new HashMap<>(),
new HashMap<>(),
"IntrospectionQuery");
}

public static GraphQLRequest createQueryOnlyRequest(String query) {
return new GraphQLRequest(query, new HashMap<>(), null);
return new GraphQLRequest(query, new HashMap<>(), new HashMap<>(), null);
}

public String getQuery() {
Expand All @@ -56,6 +69,16 @@ public void setVariables(Map<String, Object> variables) {
}
}

public Map<String, Object> getExtensions() {
return extensions;
}

public void setExtensions(Map<String, Object> extensions) {
if (extensions != null) {
this.extensions = extensions;
}
}

public String getOperationName() {
return extractOperationName(query, operationName, null);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package graphql.kickstart.execution;

public class ObjectMapDeserializationException extends RuntimeException {

ObjectMapDeserializationException(String message) {
super(message);
}

ObjectMapDeserializationException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package graphql.kickstart.execution;

import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.core.type.TypeReference;
import java.io.IOException;
import java.util.Map;

public class ObjectMapDeserializeHelper {

public static Map<String, Object> deserializeObjectMapObject(
Object object, ObjectCodec codec, String fieldName) {
if (object instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, Object> genericObjectMap = (Map<String, Object>) object;
return genericObjectMap;
} else if (object instanceof String) {
try {
return codec.readValue(
codec.getFactory().createParser((String) object),
new TypeReference<Map<String, Object>>() {});
} catch (IOException e) {
throw new ObjectMapDeserializationException(
String.format("Cannot deserialize field '%s'", fieldName), e);
}
} else {
throw new ObjectMapDeserializationException(
String.format("Field '%s' should be either an object or a string", fieldName));
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
Expand All @@ -13,22 +12,7 @@ public class VariablesDeserializer extends JsonDeserializer<Map<String, Object>>

public static Map<String, Object> deserializeVariablesObject(
Object variables, ObjectCodec codec) {
if (variables instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, Object> genericVariables = (Map<String, Object>) variables;
return genericVariables;
} else if (variables instanceof String) {
try {
return codec.readValue(
codec.getFactory().createParser((String) variables),
new TypeReference<Map<String, Object>>() {});
} catch (IOException e) {
throw new VariablesDeserializationException("Cannot deserialize variables", e);
}
} else {
throw new VariablesDeserializationException(
"Variables should be either an object or a string");
}
return ObjectMapDeserializeHelper.deserializeObjectMapObject(variables, codec, "variables");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ private ExecutionInput createExecutionInput(
.context(context)
.root(root)
.variables(graphQLRequest.getVariables())
.extensions(graphQLRequest.getExtensions())
.dataLoaderRegistry(context.getDataLoaderRegistry())
.executionId(ExecutionId.generate())
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ public GraphQLInvocationInput getGraphQLInvocationInput(

if (isSingleQuery(query)) {
Map<String, Object> variables = getVariables(request);
Map<String, Object> extensions = getExtensions(request);
String operationName = request.getParameter("operationName");
GraphQLRequest graphqlRequest = new GraphQLRequest(query, variables, operationName);
GraphQLRequest graphqlRequest =
new GraphQLRequest(query, variables, extensions, operationName);
return invocationInputFactory.createReadOnly(graphqlRequest, request, response);
}

Expand All @@ -61,4 +63,11 @@ private Map<String, Object> getVariables(HttpServletRequest request) {
.map(HashMap::new)
.orElseGet(HashMap::new);
}

private Map<String, Object> getExtensions(HttpServletRequest request) {
return Optional.ofNullable(request.getParameter("extensions"))
.map(graphQLObjectMapper::deserializeExtensions)
.map(HashMap::new)
.orElseGet(HashMap::new);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,20 @@ private GraphQLRequest buildRequestFromQuery(
graphQLObjectMapper.deserializeVariables(read(variablesItem.get().getInputStream()));
}

Map<String, Object> extensions = null;
final Optional<Part> extensionsItem = getPart(parts, "extensions");
if (extensionsItem.isPresent()) {
extensions =
graphQLObjectMapper.deserializeExtensions(read(extensionsItem.get().getInputStream()));
}

String operationName = null;
final Optional<Part> operationNameItem = getPart(parts, "operationName");
if (operationNameItem.isPresent()) {
operationName = read(operationNameItem.get().getInputStream()).trim();
}

return new GraphQLRequest(query, variables, operationName);
return new GraphQLRequest(query, variables, extensions, operationName);
}

private String read(InputStream inputStream) throws IOException {
Expand Down