Skip to content

Commit f8f6a3e

Browse files
committed
Register batch load function by name
This is an alternative to providing the key and value types, which are only used to form the DataLoader name. See gh-130
1 parent d68edb4 commit f8f6a3e

File tree

4 files changed

+63
-21
lines changed

4 files changed

+63
-21
lines changed

spring-graphql/src/main/java/org/springframework/graphql/execution/BatchLoaderRegistry.java

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,39 @@
4444
public interface BatchLoaderRegistry {
4545

4646
/**
47-
* Start the registration of a new function for batch loading data values by
48-
* specifying the key and value types.
49-
* @param keyType the type of the key that identifies the value
50-
* @param valueType the type of the data value
47+
* Begin the registration of a new batch load function by specifying the
48+
* types of the keys and values that will be used as input and output.
49+
*
50+
* <p>When this method is used, the name for the
51+
* {@link org.dataloader.DataLoader} is automatically set as defined in
52+
* {@link RegistrationSpec#withName(String)}, and likewise,
53+
* {@code @SchemaMapping} handler methods can transparenly locate and
54+
* inject a {@code DataLoader<T>} argument based on the generic type
55+
* {@code <T>}.
56+
*
57+
* @param keyType the type of keys that will be used as input
58+
* @param valueType the type of value that will be returned as output
5159
* @param <K> the key type
5260
* @param <V> the value type
5361
* @return a spec to complete the registration
5462
*/
5563
<K, V> RegistrationSpec<K, V> forTypePair(Class<K> keyType, Class<V> valueType);
5664

65+
/**
66+
* Begin the registration of a new batch load function by specifying the
67+
* name for the {@link org.dataloader.DataLoader}.
68+
*
69+
* <p><strong>Note:</strong> when this method is used, the parameter name
70+
* of a {@code DataLoader<T>} argument in a {@code @SchemaMapping} handler
71+
* method needs to match the name given here.
72+
*
73+
* @param name the name to use to register a {@code DataLoader}
74+
* @param <K> the type of keys that will be used as input
75+
* @param <V> the type of values that will be used as output
76+
* @return a spec to complete the registration
77+
*/
78+
<K, V> RegistrationSpec<K, V> forName(String name);
79+
5780

5881
/**
5982
* Spec to complete the registration of a batch loading function.
@@ -66,7 +89,8 @@ interface RegistrationSpec<K, V> {
6689
/**
6790
* Customize the name under which the {@link org.dataloader.DataLoader}
6891
* is registered and can be accessed in the data layer.
69-
* <p>By default, this is the full class name of the value type.
92+
* <p>By default, this is the full class name of the value type, if the
93+
* value type is specified via {@link #forTypePair(Class, Class)}.
7094
* @param name the name to use
7195
* @return a spec to complete the registration
7296
*/

spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultBatchLoaderRegistry.java

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
import reactor.core.publisher.Flux;
3434
import reactor.core.publisher.Mono;
3535

36+
import org.springframework.lang.Nullable;
37+
import org.springframework.util.Assert;
38+
import org.springframework.util.StringUtils;
39+
3640
/**
3741
* A default implementation of {@link BatchLoaderRegistry} that accepts
3842
* registrations, and also an implementation of {@link DataLoaderRegistrar} to
@@ -50,7 +54,12 @@ public class DefaultBatchLoaderRegistry implements BatchLoaderRegistry, DataLoad
5054

5155
@Override
5256
public <K, V> RegistrationSpec<K, V> forTypePair(Class<K> keyType, Class<V> valueType) {
53-
return new DefaultRegistrationSpec<>(valueType.getName());
57+
return new DefaultRegistrationSpec<>(valueType);
58+
}
59+
60+
@Override
61+
public <K, V> RegistrationSpec<K, V> forName(String name) {
62+
return new DefaultRegistrationSpec<>(name);
5463
}
5564

5665
@Override
@@ -75,12 +84,21 @@ private void registerDataLoader(String name, DataLoader<?, ?> dataLoader, DataLo
7584

7685
private class DefaultRegistrationSpec<K, V> implements RegistrationSpec<K, V> {
7786

87+
@Nullable
88+
private final Class<?> valueType;
89+
90+
@Nullable
7891
private String name;
7992

8093
private DataLoaderOptions options = DataLoaderOptions.newOptions();
8194

95+
public DefaultRegistrationSpec(Class<V> valueType) {
96+
this.valueType = valueType;
97+
}
98+
8299
public DefaultRegistrationSpec(String name) {
83100
this.name = name;
101+
this.valueType = null;
84102
}
85103

86104
@Override
@@ -104,13 +122,21 @@ public RegistrationSpec<K, V> withOptions(DataLoaderOptions options) {
104122
@Override
105123
public void registerBatchLoader(BiFunction<List<K>, BatchLoaderEnvironment, Flux<V>> loader) {
106124
DefaultBatchLoaderRegistry.this.loaders.add(
107-
new ReactorBatchLoader<>(this.name, loader, this.options));
125+
new ReactorBatchLoader<>(initName(), loader, this.options));
108126
}
109127

110128
@Override
111129
public void registerMappedBatchLoader(BiFunction<Set<K>, BatchLoaderEnvironment, Mono<Map<K, V>>> loader) {
112130
DefaultBatchLoaderRegistry.this.mappedLoaders.add(
113-
new ReactorMappedBatchLoader<>(this.name, loader, this.options));
131+
new ReactorMappedBatchLoader<>(initName(), loader, this.options));
132+
}
133+
134+
private String initName() {
135+
if (StringUtils.hasText(this.name)) {
136+
return this.name;
137+
}
138+
Assert.notNull(this.valueType, "Value type not available to select a default DataLoader name.");
139+
return (StringUtils.hasText(this.name) ? this.name : this.valueType.getName());
114140
}
115141
}
116142

spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/DataLoaderArgumentResolverTests.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import org.springframework.core.DefaultParameterNameDiscoverer;
2929
import org.springframework.core.MethodParameter;
3030
import org.springframework.graphql.Author;
31-
import org.springframework.graphql.Book;
3231
import org.springframework.graphql.execution.BatchLoaderRegistry;
3332
import org.springframework.graphql.execution.DefaultBatchLoaderRegistry;
3433
import org.springframework.util.ClassUtils;
@@ -57,6 +56,7 @@ void supportsParameter() {
5756

5857
@Test
5958
void resolveArgument() {
59+
6060
DataFetchingEnvironment environment = initEnvironment(registry ->
6161
registry.forTypePair(Long.class, Author.class).registerBatchLoader((ids, env) -> Flux.empty()));
6262

@@ -67,9 +67,7 @@ void resolveArgument() {
6767
@Test
6868
void resolveArgumentViaParameterName() {
6969
DataFetchingEnvironment environment = initEnvironment(registry ->
70-
registry.forTypePair(Long.class, Author.class)
71-
.withName("namedDataLoader")
72-
.registerBatchLoader((ids, env) -> Flux.empty()));
70+
registry.forName("namedDataLoader").registerBatchLoader((ids, env) -> Flux.empty()));
7371

7472
MethodParameter parameter = initParameter(1);
7573
parameter.initParameterNameDiscovery(new DefaultParameterNameDiscoverer());
@@ -90,9 +88,7 @@ void resolveArgumentFailureWithoutGenericType() {
9088
@Test
9189
void resolveArgumentFailureWithoutParameterName() {
9290
DataFetchingEnvironment environment = initEnvironment(registry ->
93-
registry.forTypePair(Long.class, Author.class)
94-
.withName("namedDataLoader")
95-
.registerBatchLoader((ids, env) -> Flux.empty()));
91+
registry.forName("namedDataLoader").registerBatchLoader((ids, env) -> Flux.empty()));
9692

9793
MethodParameter parameter = initParameter(1);
9894
// Skip ParameterNameDiscovery
@@ -104,9 +100,7 @@ void resolveArgumentFailureWithoutParameterName() {
104100
@Test
105101
void resolveArgumentFailureNoMatch() {
106102
DataFetchingEnvironment environment = initEnvironment(registry ->
107-
registry.forTypePair(Long.class, Book.class)
108-
.withName("bookDataLoader")
109-
.registerBatchLoader((ids, env) -> Flux.empty()));
103+
registry.forName("bookDataLoader").registerBatchLoader((ids, env) -> Flux.empty()));
110104

111105
MethodParameter parameter = initParameter(0);
112106
parameter.initParameterNameDiscovery(new DefaultParameterNameDiscoverer());

spring-graphql/src/test/java/org/springframework/graphql/execution/DefaultBatchLoaderRegistryTests.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,7 @@ void batchLoaderWithCustomNameAndOptions() {
6565
String name = "myLoader";
6666
StatisticsCollector collector = new NoOpStatisticsCollector();
6767

68-
this.batchLoaderRegistry
69-
.forTypePair(String.class, Book.class)
70-
.withName(name)
68+
this.batchLoaderRegistry.forName(name)
7169
.withOptions(options -> options.setStatisticsCollector(() -> collector))
7270
.registerBatchLoader((keys, environment) -> Flux.empty());
7371

0 commit comments

Comments
 (0)