|
28 | 28 | import java.util.Map;
|
29 | 29 | import java.util.Set;
|
30 | 30 | import java.util.concurrent.Callable;
|
| 31 | +import java.util.concurrent.CompletableFuture; |
31 | 32 | import java.util.concurrent.Executor;
|
32 | 33 | import java.util.function.BiConsumer;
|
33 | 34 | import java.util.function.Consumer;
|
@@ -349,8 +350,7 @@ public void configure(RuntimeWiring.Builder runtimeWiringBuilder) {
|
349 | 350 | info, this.argumentResolvers, this.validationHelper, this.exceptionResolver, this.executor);
|
350 | 351 | }
|
351 | 352 | else {
|
352 |
| - String dataLoaderKey = registerBatchLoader(info); |
353 |
| - dataFetcher = new BatchMappingDataFetcher(dataLoaderKey); |
| 353 | + dataFetcher = registerBatchLoader(info); |
354 | 354 | }
|
355 | 355 | runtimeWiringBuilder.type(info.getCoordinates().getTypeName(), typeBuilder ->
|
356 | 356 | typeBuilder.dataFetcher(info.getCoordinates().getFieldName(), dataFetcher));
|
@@ -502,38 +502,49 @@ private String formatMappings(Class<?> handlerType, Collection<MappingInfo> info
|
502 | 502 | .collect(Collectors.joining("\n\t", "\n\t" + formattedType + ":" + "\n\t", ""));
|
503 | 503 | }
|
504 | 504 |
|
505 |
| - private String registerBatchLoader(MappingInfo info) { |
| 505 | + private DataFetcher<Object> registerBatchLoader(MappingInfo info) { |
506 | 506 | if (!info.isBatchMapping()) {
|
507 | 507 | throw new IllegalArgumentException("Not a @BatchMapping method: " + info);
|
508 | 508 | }
|
509 | 509 |
|
510 | 510 | String dataLoaderKey = info.getCoordinates().toString();
|
511 | 511 | BatchLoaderRegistry registry = obtainApplicationContext().getBean(BatchLoaderRegistry.class);
|
| 512 | + BatchLoaderRegistry.RegistrationSpec<Object, Object> registration = registry.forName(dataLoaderKey); |
| 513 | + if (info.getMaxBatchSize() > 0) { |
| 514 | + registration.withOptions(options -> options.setMaxBatchSize(info.getMaxBatchSize())); |
| 515 | + } |
512 | 516 |
|
513 | 517 | HandlerMethod handlerMethod = info.getHandlerMethod();
|
514 | 518 | BatchLoaderHandlerMethod invocable = new BatchLoaderHandlerMethod(handlerMethod, this.executor);
|
515 | 519 |
|
516 | 520 | MethodParameter returnType = handlerMethod.getReturnType();
|
517 | 521 | Class<?> clazz = returnType.getParameterType();
|
518 |
| - Class<?> nestedClass = (clazz.equals(Callable.class) ? returnType.nested().getNestedParameterType() : clazz); |
519 | 522 |
|
520 |
| - BatchLoaderRegistry.RegistrationSpec<Object, Object> registration = registry.forName(dataLoaderKey); |
521 |
| - if (info.getMaxBatchSize() > 0) { |
522 |
| - registration.withOptions(options -> options.setMaxBatchSize(info.getMaxBatchSize())); |
| 523 | + if (clazz.equals(Callable.class)) { |
| 524 | + returnType = returnType.nested(); |
| 525 | + clazz = returnType.getNestedParameterType(); |
523 | 526 | }
|
524 | 527 |
|
525 |
| - if (clazz.equals(Flux.class) || Collection.class.isAssignableFrom(nestedClass)) { |
| 528 | + if (clazz.equals(Flux.class) || Collection.class.isAssignableFrom(clazz)) { |
526 | 529 | registration.registerBatchLoader(invocable::invokeForIterable);
|
| 530 | + ResolvableType valueType = ResolvableType.forMethodParameter(returnType.nested()); |
| 531 | + return new BatchMappingDataFetcher(info, valueType, dataLoaderKey); |
527 | 532 | }
|
528 |
| - else if (clazz.equals(Mono.class) || nestedClass.equals(Map.class)) { |
529 |
| - registration.registerMappedBatchLoader(invocable::invokeForMap); |
| 533 | + |
| 534 | + if (clazz.equals(Mono.class)) { |
| 535 | + returnType = returnType.nested(); |
| 536 | + clazz = returnType.getNestedParameterType(); |
530 | 537 | }
|
531 |
| - else { |
532 |
| - throw new IllegalStateException("@BatchMapping method is expected to return " + |
533 |
| - "Flux<V>, List<V>, Mono<Map<K, V>>, or Map<K, V>: " + handlerMethod); |
| 538 | + |
| 539 | + if (Map.class.isAssignableFrom(clazz)) { |
| 540 | + registration.registerMappedBatchLoader(invocable::invokeForMap); |
| 541 | + ResolvableType valueType = ResolvableType.forMethodParameter(returnType.nested(1)); |
| 542 | + return new BatchMappingDataFetcher(info, valueType, dataLoaderKey); |
534 | 543 | }
|
535 | 544 |
|
536 |
| - return dataLoaderKey; |
| 545 | + throw new IllegalStateException( |
| 546 | + "@BatchMapping method is expected to return " + |
| 547 | + "Mono<Map<K, V>>, Map<K, V>, Flux<V>, or Collection<V>: " + handlerMethod); |
537 | 548 | }
|
538 | 549 |
|
539 | 550 | /**
|
@@ -715,20 +726,34 @@ public String toString() {
|
715 | 726 | }
|
716 | 727 |
|
717 | 728 |
|
718 |
| - static class BatchMappingDataFetcher implements DataFetcher<Object> { |
| 729 | + static class BatchMappingDataFetcher implements DataFetcher<Object>, SelfDescribingDataFetcher<Object> { |
| 730 | + |
| 731 | + private final MappingInfo info; |
| 732 | + |
| 733 | + private final ResolvableType returnType; |
719 | 734 |
|
720 | 735 | private final String dataLoaderKey;
|
721 | 736 |
|
722 |
| - BatchMappingDataFetcher(String dataLoaderKey) { |
| 737 | + BatchMappingDataFetcher(MappingInfo info, ResolvableType valueType, String dataLoaderKey) { |
| 738 | + this.info = info; |
| 739 | + this.returnType = ResolvableType.forClassWithGenerics(CompletableFuture.class, valueType); |
723 | 740 | this.dataLoaderKey = dataLoaderKey;
|
724 | 741 | }
|
725 | 742 |
|
| 743 | + @Override |
| 744 | + public String getDescription() { |
| 745 | + return "@BatchMapping " + this.info.getHandlerMethod().getShortLogMessage(); |
| 746 | + } |
| 747 | + |
| 748 | + @Override |
| 749 | + public ResolvableType getReturnType() { |
| 750 | + return this.returnType; |
| 751 | + } |
| 752 | + |
726 | 753 | @Override
|
727 | 754 | public Object get(DataFetchingEnvironment env) {
|
728 | 755 | DataLoader<?, ?> dataLoader = env.getDataLoaderRegistry().getDataLoader(this.dataLoaderKey);
|
729 |
| - if (dataLoader == null) { |
730 |
| - throw new IllegalStateException("No DataLoader for key '" + this.dataLoaderKey + "'"); |
731 |
| - } |
| 756 | + Assert.state(dataLoader != null, "No DataLoader for key '" + this.dataLoaderKey + "'"); |
732 | 757 | return dataLoader.load(env.getSource());
|
733 | 758 | }
|
734 | 759 | }
|
|
0 commit comments