diff --git a/src/main/java/graphql/annotations/GraphQLAnnotations.java b/src/main/java/graphql/annotations/GraphQLAnnotations.java index e0becc44..9c4d00a3 100644 --- a/src/main/java/graphql/annotations/GraphQLAnnotations.java +++ b/src/main/java/graphql/annotations/GraphQLAnnotations.java @@ -60,6 +60,9 @@ import static graphql.schema.GraphQLInterfaceType.newInterface; import static graphql.schema.GraphQLObjectType.newObject; import static graphql.schema.GraphQLUnionType.newUnionType; +import static java.util.Arrays.stream; +import static java.util.Objects.isNull; +import static java.util.Objects.nonNull; /** * A utility class for extracting GraphQL data structures from annotated @@ -313,7 +316,19 @@ protected GraphQLFieldDefinition getField(Field field) throws GraphQLAnnotations } GraphQLDataFetcher dataFetcher = field.getAnnotation(GraphQLDataFetcher.class); - DataFetcher actualDataFetcher = dataFetcher != null ? newInstance(dataFetcher.value()) : null; + DataFetcher actualDataFetcher = null; + if (nonNull(dataFetcher)) { + final String[] args = dataFetcher.args(); + if (args.length == 0) { + actualDataFetcher = newInstance(dataFetcher.value()); + } else { + try { + final Constructor ctr = dataFetcher.value().getDeclaredConstructor( + stream(args).map(v -> String.class).toArray(Class[]::new)); + actualDataFetcher = constructNewInstance(ctr, (Object[]) args); + } catch (final NoSuchMethodException e) {} + } + } if (actualDataFetcher == null) { diff --git a/src/main/java/graphql/annotations/GraphQLDataFetcher.java b/src/main/java/graphql/annotations/GraphQLDataFetcher.java index 7aac3fd7..1d521dae 100644 --- a/src/main/java/graphql/annotations/GraphQLDataFetcher.java +++ b/src/main/java/graphql/annotations/GraphQLDataFetcher.java @@ -25,4 +25,5 @@ @Retention(RetentionPolicy.RUNTIME) public @interface GraphQLDataFetcher { Class value(); + String[] args() default {}; } diff --git a/src/test/java/graphql/annotations/GraphQLDataFetcherTest.java b/src/test/java/graphql/annotations/GraphQLDataFetcherTest.java new file mode 100644 index 00000000..ee87cb97 --- /dev/null +++ b/src/test/java/graphql/annotations/GraphQLDataFetcherTest.java @@ -0,0 +1,83 @@ +/** + * Copyright 2016 Yurii Rashkovskii + * + * 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 + * + * http://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 + */ +package graphql.annotations; + +import java.util.HashMap; + +import graphql.ExecutionResult; +import graphql.GraphQL; +import graphql.schema.DataFetcher; +import graphql.schema.DataFetchingEnvironment; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLSchema; +import graphql.schema.PropertyDataFetcher; +import org.testng.annotations.Test; + +import static graphql.schema.GraphQLSchema.newSchema; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; + +public class GraphQLDataFetcherTest { + + @Test + public void shouldUsePreferredConstructor() { + // Given + final GraphQLObjectType object = GraphQLAnnotations.object(GraphQLDataFetcherTest.TestGraphQLQuery.class); + final GraphQLSchema schema = newSchema().query(object).build(); + final GraphQL graphql = new GraphQL(schema); + + // When + final ExecutionResult result = graphql.execute("{sample {isGreat}}"); + + // Then + final HashMap data = (HashMap) result.getData(); + assertNotNull(data); + assertTrue(((HashMap)data.get("sample")).get("isGreat")); + } + + @GraphQLName("Query") + public static class TestGraphQLQuery { + @GraphQLField + @GraphQLDataFetcher(SampleDataFetcher.class) + public TestSample sample() { // Note that GraphQL uses TestSample to build the graph + return null; + } + } + + public static class TestSample { + @GraphQLField + @GraphQLDataFetcher(value = PropertyDataFetcher.class, args = "isGreat") + private Boolean isGreat = false; // Defaults to FieldDataFetcher + } + + public static class SampleDataFetcher implements DataFetcher { + @Override + public Object get(final DataFetchingEnvironment environment) { + return new Sample(); // Notice that it return a Sample, not a TestSample + } + } + + public static class Sample { + private Boolean isGreat = true; + + public Boolean getIsGreat() { + return isGreat; + } + + public void setIsGreat(final Boolean isGreat) { + this.isGreat = isGreat; + } + } +} \ No newline at end of file