Skip to content

Commit 4908252

Browse files
authored
Merge pull request #151 from Jahia/newInstance
Allows to defines a getInstance() method on TypeResolver/DataFetcher/…
2 parents 8df94f5 + fcea5c1 commit 4908252

File tree

3 files changed

+36
-3
lines changed

3 files changed

+36
-3
lines changed

README.md

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,26 @@ GraphQLObjectType object = GraphQLAnnotations.object(SomeObject.class);
3434

3535
## Defining Interfaces
3636

37-
This is very similar to defining objects:
37+
This is very similar to defining objects, with the addition of type resolver :
3838

3939
```java
40+
@GraphQLTypeResolver(MyTypeResolver.class)
4041
public interface SomeInterface {
4142
@GraphQLField
4243
String field();
4344
}
4445

46+
public class MyTypeResolver implements TypeResolver {
47+
GraphQLObjectType getType(TypeResolutionEnvironment env) { ... }
48+
}
49+
4550
// ...
4651
GraphQLInterfaceType object = GraphQLAnnotations.iface(SomeInterface.class);
4752
```
4853

54+
An instance of the type resolver will be created from the specified class. If a `getInstance` method is present on the
55+
class, it will be used instead of the default constructor.
56+
4957
## Fields
5058

5159
In addition to specifying a field over a Java class field, a field can be defined over a method:
@@ -108,10 +116,21 @@ public String field(@GraphQLDefaultValue(DefaultValue.class) String value) {
108116
}
109117
```
110118

119+
The `DefaultValue` class can define a `getInstance` method that will be called instead of the default constructor.
120+
111121
`@GraphQLDeprecate` and Java's `@Deprecated` can be used to specify a deprecated
112122
field.
113123

114-
You can specify a custom data fetcher for a field with `@GraphQLDataFetcher`
124+
### Custom data fetcher
125+
126+
You can specify a custom data fetcher for a field with `@GraphQLDataFetcher`. The annotation will reference a class name,
127+
which will be used as data fetcher.
128+
129+
An instance of the data fetcher will be created. The `args` attribute on the annotation can be used to specify a list of
130+
String arguments to pass to the construcor, allowing to reuse the same class on different fields, with different parameter.
131+
The `firstArgIsTargetName` attribute can also be set on `@GraphQLDataFetcher` to pass the field name as a single parameter of the constructor.
132+
133+
If no argument is needed and a `getInstance` method is present, this method will be called instead of the constructor.
115134

116135
## Type extensions
117136

src/main/java/graphql/annotations/processor/util/ReflectionKit.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import java.lang.reflect.Constructor;
2020
import java.lang.reflect.InvocationTargetException;
21+
import java.lang.reflect.Method;
22+
import java.lang.reflect.Modifier;
2123

2224
/**
2325
* A package level helper in calling reflective methods and turning them into
@@ -26,8 +28,16 @@
2628
public class ReflectionKit {
2729
public static <T> T newInstance(Class<T> clazz) throws GraphQLAnnotationsException {
2830
try {
31+
try {
32+
Method getInstance = clazz.getMethod("getInstance", new Class<?>[0]);
33+
if (Modifier.isStatic(getInstance.getModifiers()) && clazz.isAssignableFrom(getInstance.getReturnType())) {
34+
return (T) getInstance.invoke(null);
35+
}
36+
} catch (NoSuchMethodException e) {
37+
// ignore, just call the constructor
38+
}
2939
return clazz.newInstance();
30-
} catch (InstantiationException | IllegalAccessException e) {
40+
} catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
3141
throw new GraphQLAnnotationsException("Unable to instantiate class : " + clazz, e);
3242
}
3343
}

src/test/java/graphql/annotations/GraphQLInterfaceTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ public void noResolver() {
6969

7070
public static class Resolver implements TypeResolver {
7171

72+
public static Resolver getInstance() {
73+
return new Resolver();
74+
}
75+
7276
@Override
7377
public GraphQLObjectType getType(TypeResolutionEnvironment env) {
7478
try {

0 commit comments

Comments
 (0)