Skip to content

Commit c1abded

Browse files
committed
Problem: object variables are decoded as maps
However, it'd be really useful to get them back as original classes to be able to use them directly. Solution: use annotations' 0.13.1 capability to retrieve the original class
1 parent b7a2df6 commit c1abded

File tree

4 files changed

+144
-2
lines changed

4 files changed

+144
-2
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ dependencies {
118118

119119
// GraphQL
120120
compile 'com.graphql-java:graphql-java:2.2.0'
121-
compile 'com.graphql-java:graphql-java-annotations:0.13.0'
121+
compile 'com.graphql-java:graphql-java-annotations:0.13.1'
122122

123123
// JSON
124124
compile 'com.fasterxml.jackson.core:jackson-core:2.7.3'

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
version = 0.9.0
1+
version = 0.9.1
22
group = com.graphql-java
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* Copyright 2016 Yurii Rashkovskii
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
*/
15+
package graphql.servlet;
16+
17+
import com.fasterxml.jackson.core.JsonProcessingException;
18+
import com.fasterxml.jackson.databind.ObjectMapper;
19+
import graphql.annotations.GraphQLObjectTypeWrapper;
20+
import graphql.language.OperationDefinition;
21+
import graphql.language.TypeName;
22+
import graphql.language.VariableDefinition;
23+
import graphql.parser.Parser;
24+
import graphql.schema.GraphQLSchema;
25+
import graphql.schema.GraphQLType;
26+
import lombok.SneakyThrows;
27+
28+
import java.util.HashMap;
29+
import java.util.Map;
30+
import java.util.function.Consumer;
31+
32+
public class GraphQLVariables extends HashMap<String, Object> {
33+
34+
private final GraphQLSchema schema;
35+
private final String query;
36+
37+
public GraphQLVariables(GraphQLSchema schema, String query, Map<String, Object> variables) {
38+
super();
39+
this.schema = schema;
40+
this.query = query;
41+
ObjectMapper objectMapper = new ObjectMapper();
42+
new Parser().parseDocument(query).getDefinitions().stream()
43+
.filter(d -> d instanceof OperationDefinition)
44+
.map(d -> (OperationDefinition) d)
45+
.flatMap(d -> d.getVariableDefinitions().stream())
46+
.forEach(new Consumer<VariableDefinition>() {
47+
@SneakyThrows
48+
@Override public void accept(VariableDefinition d) {
49+
GraphQLType type = schema.getType(((TypeName) (d.getType())).getName());
50+
if (type instanceof GraphQLObjectTypeWrapper) {
51+
String value = objectMapper.writeValueAsString(variables.get(d.getName()));
52+
Object val = objectMapper.readValue(value, ((GraphQLObjectTypeWrapper) type).getObjectClass());
53+
GraphQLVariables.this.put(d.getName(), val);
54+
} else {
55+
GraphQLVariables.this.put(d.getName(), variables.get(d.getName()));
56+
}
57+
}
58+
});
59+
}
60+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/**
2+
* Copyright 2016 Yurii Rashkovskii
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
*/
15+
package graphql.servlet;
16+
17+
import graphql.annotations.GraphQLAnnotations;
18+
import graphql.annotations.GraphQLField;
19+
import graphql.annotations.GraphQLName;
20+
import graphql.schema.GraphQLObjectType;
21+
import graphql.schema.GraphQLSchema;
22+
import lombok.SneakyThrows;
23+
import lombok.Value;
24+
import org.testng.annotations.Test;
25+
26+
import java.util.HashMap;
27+
28+
import static org.testng.Assert.assertEquals;
29+
import static org.testng.Assert.assertTrue;
30+
31+
public class GraphQLVariablesTest {
32+
33+
public static class ComplexQueryProvider implements GraphQLQueryProvider {
34+
35+
36+
@Value
37+
public static class Data {
38+
@GraphQLField
39+
private String field1;
40+
@GraphQLField
41+
private String field2;
42+
}
43+
44+
@GraphQLName("data")
45+
public static class DataQuery {
46+
@GraphQLField
47+
public Data echo(Data data) {
48+
return data;
49+
}
50+
}
51+
52+
@Override @SneakyThrows
53+
public GraphQLObjectType getQuery() {
54+
return GraphQLAnnotations.object(DataQuery.class);
55+
}
56+
57+
@Override
58+
public Object context() {
59+
return new DataQuery();
60+
}
61+
}
62+
63+
private static final String QUERY = "query Q($d: Data) { data { echo(data: $d) { field1 field2 } } }";
64+
65+
@Test
66+
public void variableTyping() {
67+
GraphQLServlet servlet = new GraphQLServlet();
68+
ComplexQueryProvider queryProvider = new ComplexQueryProvider();
69+
servlet.bindQueryProvider(queryProvider);
70+
GraphQLSchema schema = servlet.getSchema();
71+
HashMap<String, Object> data = new HashMap<>();
72+
data.put("field1", "1");
73+
data.put("field2", "2");
74+
HashMap<String, Object> vars = new HashMap<>();
75+
vars.put("d", data);
76+
GraphQLVariables variables = new GraphQLVariables(schema, QUERY, vars);
77+
Object d = variables.get("d");
78+
assertTrue(d instanceof ComplexQueryProvider.Data);
79+
assertEquals(((ComplexQueryProvider.Data)d).getField1(), "1");
80+
assertEquals(((ComplexQueryProvider.Data)d).getField2(), "2");
81+
}
82+
}

0 commit comments

Comments
 (0)