Skip to content

Commit 43f41d2

Browse files
committed
Polishing in EntitiesDataFetcher/HandlerMethod
See gh-991
1 parent 22bbc86 commit 43f41d2

File tree

2 files changed

+44
-47
lines changed

2 files changed

+44
-47
lines changed

spring-graphql/src/main/java/org/springframework/graphql/data/federation/EntitiesDataFetcher.java

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -65,36 +65,42 @@ final class EntitiesDataFetcher implements DataFetcher<Mono<DataFetcherResult<Li
6565

6666

6767
@Override
68-
public Mono<DataFetcherResult<List<Object>>> get(DataFetchingEnvironment environment) {
69-
List<Map<String, Object>> representations = environment.getArgument(_Entity.argumentName);
68+
public Mono<DataFetcherResult<List<Object>>> get(DataFetchingEnvironment env) {
69+
List<Map<String, Object>> representations = env.getArgument(_Entity.argumentName);
70+
if (representations == null) {
71+
return Mono.error(new RepresentationException(
72+
Collections.emptyMap(), "Missing \"representations\" argument"));
73+
}
7074

71-
Set<String> batched = new HashSet<>();
72-
List<Mono<Object>> monoList = new ArrayList<>();
75+
Set<String> batchedTypes = new HashSet<>();
76+
List<Mono<?>> monoList = new ArrayList<>();
7377
for (int index = 0; index < representations.size(); index++) {
7478
Map<String, Object> map = representations.get(index);
75-
if (!(map.get("__typename") instanceof String typename)) {
79+
if (!(map.get("__typename") instanceof String type)) {
7680
Exception ex = new RepresentationException(map, "Missing \"__typename\" argument");
77-
monoList.add(resolveException(ex, environment, null, index));
81+
monoList.add(resolveException(ex, env, null, index));
7882
continue;
7983
}
80-
EntityHandlerMethod handlerMethod = this.handlerMethods.get(typename);
84+
EntityHandlerMethod handlerMethod = this.handlerMethods.get(type);
8185
if (handlerMethod == null) {
8286
Exception ex = new RepresentationException(map, "No entity fetcher");
83-
monoList.add(resolveException(ex, environment, null, index));
87+
monoList.add(resolveException(ex, env, null, index));
8488
continue;
8589
}
8690

8791
if (!handlerMethod.isBatchHandlerMethod()) {
88-
monoList.add(invokeEntityMethod(environment, handlerMethod, map, index));
89-
}
90-
else if (batched.contains(typename)) {
91-
// zip needs a value, this will be replaced by batch results
92-
monoList.add(Mono.just(Collections.emptyMap()));
92+
monoList.add(invokeEntityMethod(env, handlerMethod, map, index));
9393
}
9494
else {
95-
EntityBatchDelegate batchDelegate = new EntityBatchDelegate(environment, handlerMethod, typename);
96-
monoList.add(batchDelegate.invokeEntityBatchMethod());
97-
batched.add(typename);
95+
if (!batchedTypes.contains(type)) {
96+
EntityBatchDelegate delegate = new EntityBatchDelegate(env, representations, handlerMethod, type);
97+
monoList.add(delegate.invokeEntityBatchMethod());
98+
batchedTypes.add(type);
99+
}
100+
else {
101+
// Covered by batch invocation, but zip needs a value (to be replaced by batch results)
102+
monoList.add(Mono.just(Collections.emptyMap()));
103+
}
98104
}
99105
}
100106
return Mono.zip(monoList, Arrays::asList).map(EntitiesDataFetcher::toDataFetcherResult);
@@ -108,7 +114,7 @@ private Mono<Object> invokeEntityMethod(
108114
.onErrorResume((ex) -> resolveException(ex, env, handlerMethod, index));
109115
}
110116

111-
private Mono<Object> resolveException(
117+
private Mono<ErrorContainer> resolveException(
112118
Throwable ex, DataFetchingEnvironment env, @Nullable EntityHandlerMethod handlerMethod, int index) {
113119

114120
Throwable theEx = (ex instanceof CompletionException) ? ex.getCause() : ex;
@@ -117,8 +123,7 @@ private Mono<Object> resolveException(
117123

118124
return this.exceptionResolver.resolveException(theEx, theEnv, handler)
119125
.map(ErrorContainer::new)
120-
.switchIfEmpty(Mono.fromCallable(() -> createDefaultError(theEx, theEnv)))
121-
.cast(Object.class);
126+
.switchIfEmpty(Mono.fromCallable(() -> createDefaultError(theEx, theEnv)));
122127
}
123128

124129
private ErrorContainer createDefaultError(Throwable ex, DataFetchingEnvironment env) {
@@ -154,28 +159,30 @@ private class EntityBatchDelegate {
154159

155160
private final EntityHandlerMethod handlerMethod;
156161

157-
private final List<Map<String, Object>> representations = new ArrayList<>();
162+
private final List<Map<String, Object>> filteredRepresentations = new ArrayList<>();
158163

159164
private final List<Integer> indexes = new ArrayList<>();
160165

161166
@Nullable
162167
private List<?> resultList;
163168

164-
EntityBatchDelegate(DataFetchingEnvironment env, EntityHandlerMethod handlerMethod, String typeName) {
169+
EntityBatchDelegate(
170+
DataFetchingEnvironment env, List<Map<String, Object>> allRepresentations,
171+
EntityHandlerMethod handlerMethod, String type) {
172+
165173
this.environment = env;
166174
this.handlerMethod = handlerMethod;
167-
List<Map<String, Object>> maps = env.getArgument(_Entity.argumentName);
168-
for (int i = 0; i < maps.size(); i++) {
169-
Map<String, Object> map = maps.get(i);
170-
if (typeName.equals(map.get("__typename"))) {
171-
this.representations.add(map);
175+
for (int i = 0; i < allRepresentations.size(); i++) {
176+
Map<String, Object> map = allRepresentations.get(i);
177+
if (type.equals(map.get("__typename"))) {
178+
this.filteredRepresentations.add(map);
172179
this.indexes.add(i);
173180
}
174181
}
175182
}
176183

177184
Mono<Object> invokeEntityBatchMethod() {
178-
return this.handlerMethod.getEntities(this.environment, this.representations)
185+
return this.handlerMethod.getEntities(this.environment, this.filteredRepresentations)
179186
.mapNotNull((result) -> (((List<?>) result).isEmpty()) ? null : result)
180187
.switchIfEmpty(Mono.defer(this::handleEmptyResult))
181188
.onErrorResume(this::handleErrorResult)
@@ -186,17 +193,17 @@ Mono<Object> invokeEntityBatchMethod() {
186193
}
187194

188195
Mono<Object> handleEmptyResult() {
189-
List<Mono<Object>> exceptions = new ArrayList<>(this.indexes.size());
196+
List<Mono<?>> exceptions = new ArrayList<>(this.indexes.size());
190197
for (int i = 0; i < this.indexes.size(); i++) {
191-
Map<String, Object> map = this.representations.get(i);
198+
Map<String, Object> map = this.filteredRepresentations.get(i);
192199
Exception ex = new RepresentationNotResolvedException(map, this.handlerMethod);
193200
exceptions.add(resolveException(ex, this.environment, this.handlerMethod, this.indexes.get(i)));
194201
}
195202
return Mono.zip(exceptions, Arrays::asList);
196203
}
197204

198205
Mono<List<Object>> handleErrorResult(Throwable ex) {
199-
List<Mono<Object>> list = new ArrayList<>();
206+
List<Mono<?>> list = new ArrayList<>();
200207
for (Integer index : this.indexes) {
201208
list.add(resolveException(ex, this.environment, this.handlerMethod, index));
202209
}

spring-graphql/src/main/java/org/springframework/graphql/data/federation/EntityHandlerMethod.java

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -53,33 +53,23 @@ boolean isBatchHandlerMethod() {
5353

5454

5555
Mono<Object> getEntity(DataFetchingEnvironment env, Map<String, Object> representation) {
56-
Object[] args;
57-
try {
58-
env = EntityArgumentMethodArgumentResolver.wrap(env, representation);
59-
args = getMethodArgumentValues(env);
60-
}
61-
catch (Throwable ex) {
62-
return Mono.error(ex);
63-
}
64-
65-
return doInvoke(env, args);
56+
env = EntityArgumentMethodArgumentResolver.wrap(env, representation);
57+
return doInvoke(env);
6658
}
6759

68-
@SuppressWarnings("unchecked")
6960
Mono<Object> getEntities(DataFetchingEnvironment env, List<Map<String, Object>> representations) {
61+
env = EntityArgumentMethodArgumentResolver.wrap(env, representations);
62+
return doInvoke(env);
63+
}
64+
65+
private Mono<Object> doInvoke(DataFetchingEnvironment env) {
7066
Object[] args;
7167
try {
72-
env = EntityArgumentMethodArgumentResolver.wrap(env, representations);
7368
args = getMethodArgumentValues(env);
7469
}
7570
catch (Throwable ex) {
7671
return Mono.error(ex);
7772
}
78-
79-
return doInvoke(env, args);
80-
}
81-
82-
private Mono<Object> doInvoke(DataFetchingEnvironment env, Object[] args) {
8373
Object result = doInvoke(env.getGraphQlContext(), args);
8474
return ReactiveAdapterRegistryHelper.toMono(result);
8575
}

0 commit comments

Comments
 (0)