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
This commit is contained in:
@@ -44,16 +44,39 @@ import reactor.core.publisher.Mono;
|
||||
public interface BatchLoaderRegistry {
|
||||
|
||||
/**
|
||||
* Start the registration of a new function for batch loading data values by
|
||||
* specifying the key and value types.
|
||||
* @param keyType the type of the key that identifies the value
|
||||
* @param valueType the type of the data value
|
||||
* Begin the registration of a new batch load function by specifying the
|
||||
* types of the keys and values that will be used as input and output.
|
||||
*
|
||||
* <p>When this method is used, the name for the
|
||||
* {@link org.dataloader.DataLoader} is automatically set as defined in
|
||||
* {@link RegistrationSpec#withName(String)}, and likewise,
|
||||
* {@code @SchemaMapping} handler methods can transparenly locate and
|
||||
* inject a {@code DataLoader<T>} argument based on the generic type
|
||||
* {@code <T>}.
|
||||
*
|
||||
* @param keyType the type of keys that will be used as input
|
||||
* @param valueType the type of value that will be returned as output
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
* @return a spec to complete the registration
|
||||
*/
|
||||
<K, V> RegistrationSpec<K, V> forTypePair(Class<K> keyType, Class<V> valueType);
|
||||
|
||||
/**
|
||||
* Begin the registration of a new batch load function by specifying the
|
||||
* name for the {@link org.dataloader.DataLoader}.
|
||||
*
|
||||
* <p><strong>Note:</strong> when this method is used, the parameter name
|
||||
* of a {@code DataLoader<T>} argument in a {@code @SchemaMapping} handler
|
||||
* method needs to match the name given here.
|
||||
*
|
||||
* @param name the name to use to register a {@code DataLoader}
|
||||
* @param <K> the type of keys that will be used as input
|
||||
* @param <V> the type of values that will be used as output
|
||||
* @return a spec to complete the registration
|
||||
*/
|
||||
<K, V> RegistrationSpec<K, V> forName(String name);
|
||||
|
||||
|
||||
/**
|
||||
* Spec to complete the registration of a batch loading function.
|
||||
@@ -66,7 +89,8 @@ public interface BatchLoaderRegistry {
|
||||
/**
|
||||
* Customize the name under which the {@link org.dataloader.DataLoader}
|
||||
* is registered and can be accessed in the data layer.
|
||||
* <p>By default, this is the full class name of the value type.
|
||||
* <p>By default, this is the full class name of the value type, if the
|
||||
* value type is specified via {@link #forTypePair(Class, Class)}.
|
||||
* @param name the name to use
|
||||
* @return a spec to complete the registration
|
||||
*/
|
||||
|
||||
@@ -33,6 +33,10 @@ import org.dataloader.MappedBatchLoaderWithContext;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* A default implementation of {@link BatchLoaderRegistry} that accepts
|
||||
* registrations, and also an implementation of {@link DataLoaderRegistrar} to
|
||||
@@ -50,7 +54,12 @@ public class DefaultBatchLoaderRegistry implements BatchLoaderRegistry, DataLoad
|
||||
|
||||
@Override
|
||||
public <K, V> RegistrationSpec<K, V> forTypePair(Class<K> keyType, Class<V> valueType) {
|
||||
return new DefaultRegistrationSpec<>(valueType.getName());
|
||||
return new DefaultRegistrationSpec<>(valueType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> RegistrationSpec<K, V> forName(String name) {
|
||||
return new DefaultRegistrationSpec<>(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -75,12 +84,21 @@ public class DefaultBatchLoaderRegistry implements BatchLoaderRegistry, DataLoad
|
||||
|
||||
private class DefaultRegistrationSpec<K, V> implements RegistrationSpec<K, V> {
|
||||
|
||||
@Nullable
|
||||
private final Class<?> valueType;
|
||||
|
||||
@Nullable
|
||||
private String name;
|
||||
|
||||
private DataLoaderOptions options = DataLoaderOptions.newOptions();
|
||||
|
||||
public DefaultRegistrationSpec(Class<V> valueType) {
|
||||
this.valueType = valueType;
|
||||
}
|
||||
|
||||
public DefaultRegistrationSpec(String name) {
|
||||
this.name = name;
|
||||
this.valueType = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -104,13 +122,21 @@ public class DefaultBatchLoaderRegistry implements BatchLoaderRegistry, DataLoad
|
||||
@Override
|
||||
public void registerBatchLoader(BiFunction<List<K>, BatchLoaderEnvironment, Flux<V>> loader) {
|
||||
DefaultBatchLoaderRegistry.this.loaders.add(
|
||||
new ReactorBatchLoader<>(this.name, loader, this.options));
|
||||
new ReactorBatchLoader<>(initName(), loader, this.options));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerMappedBatchLoader(BiFunction<Set<K>, BatchLoaderEnvironment, Mono<Map<K, V>>> loader) {
|
||||
DefaultBatchLoaderRegistry.this.mappedLoaders.add(
|
||||
new ReactorMappedBatchLoader<>(this.name, loader, this.options));
|
||||
new ReactorMappedBatchLoader<>(initName(), loader, this.options));
|
||||
}
|
||||
|
||||
private String initName() {
|
||||
if (StringUtils.hasText(this.name)) {
|
||||
return this.name;
|
||||
}
|
||||
Assert.notNull(this.valueType, "Value type not available to select a default DataLoader name.");
|
||||
return (StringUtils.hasText(this.name) ? this.name : this.valueType.getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ import reactor.core.publisher.Flux;
|
||||
import org.springframework.core.DefaultParameterNameDiscoverer;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.graphql.Author;
|
||||
import org.springframework.graphql.Book;
|
||||
import org.springframework.graphql.execution.BatchLoaderRegistry;
|
||||
import org.springframework.graphql.execution.DefaultBatchLoaderRegistry;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -57,6 +56,7 @@ public class DataLoaderArgumentResolverTests {
|
||||
|
||||
@Test
|
||||
void resolveArgument() {
|
||||
|
||||
DataFetchingEnvironment environment = initEnvironment(registry ->
|
||||
registry.forTypePair(Long.class, Author.class).registerBatchLoader((ids, env) -> Flux.empty()));
|
||||
|
||||
@@ -67,9 +67,7 @@ public class DataLoaderArgumentResolverTests {
|
||||
@Test
|
||||
void resolveArgumentViaParameterName() {
|
||||
DataFetchingEnvironment environment = initEnvironment(registry ->
|
||||
registry.forTypePair(Long.class, Author.class)
|
||||
.withName("namedDataLoader")
|
||||
.registerBatchLoader((ids, env) -> Flux.empty()));
|
||||
registry.forName("namedDataLoader").registerBatchLoader((ids, env) -> Flux.empty()));
|
||||
|
||||
MethodParameter parameter = initParameter(1);
|
||||
parameter.initParameterNameDiscovery(new DefaultParameterNameDiscoverer());
|
||||
@@ -90,9 +88,7 @@ public class DataLoaderArgumentResolverTests {
|
||||
@Test
|
||||
void resolveArgumentFailureWithoutParameterName() {
|
||||
DataFetchingEnvironment environment = initEnvironment(registry ->
|
||||
registry.forTypePair(Long.class, Author.class)
|
||||
.withName("namedDataLoader")
|
||||
.registerBatchLoader((ids, env) -> Flux.empty()));
|
||||
registry.forName("namedDataLoader").registerBatchLoader((ids, env) -> Flux.empty()));
|
||||
|
||||
MethodParameter parameter = initParameter(1);
|
||||
// Skip ParameterNameDiscovery
|
||||
@@ -104,9 +100,7 @@ public class DataLoaderArgumentResolverTests {
|
||||
@Test
|
||||
void resolveArgumentFailureNoMatch() {
|
||||
DataFetchingEnvironment environment = initEnvironment(registry ->
|
||||
registry.forTypePair(Long.class, Book.class)
|
||||
.withName("bookDataLoader")
|
||||
.registerBatchLoader((ids, env) -> Flux.empty()));
|
||||
registry.forName("bookDataLoader").registerBatchLoader((ids, env) -> Flux.empty()));
|
||||
|
||||
MethodParameter parameter = initParameter(0);
|
||||
parameter.initParameterNameDiscovery(new DefaultParameterNameDiscoverer());
|
||||
|
||||
@@ -65,9 +65,7 @@ public class DefaultBatchLoaderRegistryTests {
|
||||
String name = "myLoader";
|
||||
StatisticsCollector collector = new NoOpStatisticsCollector();
|
||||
|
||||
this.batchLoaderRegistry
|
||||
.forTypePair(String.class, Book.class)
|
||||
.withName(name)
|
||||
this.batchLoaderRegistry.forName(name)
|
||||
.withOptions(options -> options.setStatisticsCollector(() -> collector))
|
||||
.registerBatchLoader((keys, environment) -> Flux.empty());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user