Skip to content

Commit 78af222

Browse files
committed
Merge pull request graphql-java#26 from erikogenvik/fieldfetch
Added fetching from raw fields.
2 parents b72a06f + 345d926 commit 78af222

3 files changed

Lines changed: 120 additions & 1 deletion

File tree

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package graphql.schema;
2+
3+
4+
import java.lang.reflect.Field;
5+
import java.lang.reflect.InvocationTargetException;
6+
import java.lang.reflect.Method;
7+
import java.util.Map;
8+
9+
import static graphql.Scalars.GraphQLBoolean;
10+
11+
/**
12+
* Fetches data directly from a field.
13+
*/
14+
public class FieldDataFetcher implements DataFetcher {
15+
16+
/**
17+
* The name of the field.
18+
*/
19+
private final String fieldName;
20+
21+
/**
22+
* Ctor.
23+
* @param fieldName The name of the field.
24+
*/
25+
public FieldDataFetcher(String fieldName) {
26+
this.fieldName = fieldName;
27+
}
28+
29+
@Override
30+
public Object get(DataFetchingEnvironment environment) {
31+
Object source = environment.getSource();
32+
if (source == null) return null;
33+
if (source instanceof Map) {
34+
return ((Map<?, ?>) source).get(fieldName);
35+
}
36+
return getFieldValue(source, environment.getFieldType());
37+
}
38+
39+
/**
40+
* Uses introspection to get the field value.
41+
* @param object The object being acted on.
42+
* @param outputType The output type; ignored in this case.
43+
* @return An object, or null.
44+
*/
45+
private Object getFieldValue(Object object, GraphQLOutputType outputType) {
46+
try {
47+
Field field = object.getClass().getField(fieldName);
48+
return field.get(object);
49+
} catch (NoSuchFieldException e) {
50+
return null;
51+
} catch (IllegalAccessException e) {
52+
throw new RuntimeException(e);
53+
}
54+
}
55+
}

src/main/java/graphql/schema/GraphQLFieldDefinition.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ public static class Builder {
8383
private DataFetcher dataFetcher;
8484
private List<GraphQLArgument> arguments = new ArrayList<>();
8585
private String deprecationReason;
86+
private boolean isField;
8687

8788

8889
public Builder name(String name) {
@@ -115,6 +116,15 @@ public Object get(DataFetchingEnvironment environment) {
115116
return this;
116117
}
117118

119+
/**
120+
* Get the data from a field.
121+
* @return
122+
*/
123+
public Builder fetchField() {
124+
this.isField = true;
125+
return this;
126+
}
127+
118128
public Builder argument(GraphQLArgument argument) {
119129
this.arguments.add(argument);
120130
return this;
@@ -132,7 +142,11 @@ public Builder deprecate(String deprecationReason) {
132142

133143
public GraphQLFieldDefinition build() {
134144
if (dataFetcher == null) {
135-
dataFetcher = new PropertyDataFetcher(name);
145+
if (isField) {
146+
dataFetcher = new FieldDataFetcher(name);
147+
} else {
148+
dataFetcher = new PropertyDataFetcher(name);
149+
}
136150
}
137151
return new GraphQLFieldDefinition(name, description, type, dataFetcher, arguments, deprecationReason);
138152
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package graphql
2+
3+
import graphql.schema.DataFetchingEnvironment
4+
import graphql.schema.FieldDataFetcher
5+
import graphql.schema.PropertyDataFetcher
6+
import spock.lang.Specification
7+
8+
import static graphql.Scalars.GraphQLString
9+
10+
class DataFetcherTest extends Specification {
11+
12+
class DataHolder {
13+
14+
private String privateField
15+
public String publicField
16+
17+
public String getProperty() {
18+
return privateField
19+
}
20+
21+
public void setProperty(String value) {
22+
privateField = value
23+
}
24+
}
25+
def DataHolder dataHolder
26+
27+
def setup() {
28+
dataHolder = new DataHolder();
29+
dataHolder.publicField = "publicValue"
30+
dataHolder.setProperty("propertyValue")
31+
}
32+
33+
def "get field value"() {
34+
given:
35+
def environment = new DataFetchingEnvironment(dataHolder, null, null, null, GraphQLString, null, null)
36+
when:
37+
def result = new FieldDataFetcher("publicField").get(environment)
38+
then:
39+
result == "publicValue"
40+
}
41+
42+
def "get property value"() {
43+
given:
44+
def environment = new DataFetchingEnvironment(dataHolder, null, null, null, GraphQLString, null, null)
45+
when:
46+
def result = new PropertyDataFetcher("property").get(environment)
47+
then:
48+
result == "propertyValue"
49+
}
50+
}

0 commit comments

Comments
 (0)