2
2
3
3
import com .google .common .collect .ImmutableList ;
4
4
import com .google .common .collect .Maps ;
5
+ import graphql .DuckTyped ;
5
6
import graphql .ExecutionResult ;
6
7
import graphql .ExecutionResultImpl ;
7
8
import graphql .ExperimentalApi ;
24
25
import graphql .execution .instrumentation .parameters .InstrumentationFieldCompleteParameters ;
25
26
import graphql .execution .instrumentation .parameters .InstrumentationFieldFetchParameters ;
26
27
import graphql .execution .instrumentation .parameters .InstrumentationFieldParameters ;
28
+ import graphql .execution .reactive .ReactiveSupport ;
27
29
import graphql .extensions .ExtensionsBuilder ;
28
30
import graphql .introspection .Introspection ;
29
31
import graphql .language .Argument ;
@@ -197,8 +199,8 @@ public static String mkNameForPath(List<Field> currentField) {
197
199
* @throws NonNullableFieldWasNullException in the {@link CompletableFuture} if a non-null field resolved to a null value
198
200
*/
199
201
@ SuppressWarnings ("unchecked" )
200
- protected Object /* CompletableFuture<Map<String, Object>> | Map<String, Object> */
201
- executeObject (ExecutionContext executionContext , ExecutionStrategyParameters parameters ) throws NonNullableFieldWasNullException {
202
+ @ DuckTyped ( shape = " CompletableFuture<Map<String, Object>> | Map<String, Object>" )
203
+ protected Object executeObject (ExecutionContext executionContext , ExecutionStrategyParameters parameters ) throws NonNullableFieldWasNullException {
202
204
DataLoaderDispatchStrategy dataLoaderDispatcherStrategy = executionContext .getDataLoaderDispatcherStrategy ();
203
205
dataLoaderDispatcherStrategy .executeObject (executionContext , parameters );
204
206
Instrumentation instrumentation = executionContext .getInstrumentation ();
@@ -356,8 +358,8 @@ Async.CombinedBuilder<FieldValueInfo> getAsyncFieldValueInfo(
356
358
* @throws NonNullableFieldWasNullException in the future if a non-null field resolved to a null value
357
359
*/
358
360
@ SuppressWarnings ("unchecked" )
359
- protected Object /* CompletableFuture<Object> | Object */
360
- resolveField (ExecutionContext executionContext , ExecutionStrategyParameters parameters ) {
361
+ @ DuckTyped ( shape = " CompletableFuture<Object> | Object" )
362
+ protected Object resolveField (ExecutionContext executionContext , ExecutionStrategyParameters parameters ) {
361
363
Object fieldWithInfo = resolveFieldWithInfo (executionContext , parameters );
362
364
if (fieldWithInfo instanceof CompletableFuture ) {
363
365
return ((CompletableFuture <FieldValueInfo >) fieldWithInfo ).thenCompose (FieldValueInfo ::getFieldValueFuture );
@@ -384,8 +386,8 @@ Async.CombinedBuilder<FieldValueInfo> getAsyncFieldValueInfo(
384
386
* if a nonnull field resolves to a null value
385
387
*/
386
388
@ SuppressWarnings ("unchecked" )
387
- protected Object /* CompletableFuture<FieldValueInfo> | FieldValueInfo */
388
- resolveFieldWithInfo (ExecutionContext executionContext , ExecutionStrategyParameters parameters ) {
389
+ @ DuckTyped ( shape = " CompletableFuture<FieldValueInfo> | FieldValueInfo" )
390
+ protected Object resolveFieldWithInfo (ExecutionContext executionContext , ExecutionStrategyParameters parameters ) {
389
391
GraphQLFieldDefinition fieldDef = getFieldDef (executionContext , parameters , parameters .getField ().getSingleField ());
390
392
Supplier <ExecutionStepInfo > executionStepInfo = FpKit .intraThreadMemoize (() -> createExecutionStepInfo (executionContext , parameters , fieldDef , null ));
391
393
@@ -430,16 +432,16 @@ Async.CombinedBuilder<FieldValueInfo> getAsyncFieldValueInfo(
430
432
*
431
433
* @throws NonNullableFieldWasNullException in the future if a non null field resolves to a null value
432
434
*/
433
- protected Object /* CompletableFuture<FetchedValue> | FetchedValue>*/
434
- fetchField (ExecutionContext executionContext , ExecutionStrategyParameters parameters ) {
435
+ @ DuckTyped ( shape = " CompletableFuture<FetchedValue> | FetchedValue" )
436
+ protected Object fetchField (ExecutionContext executionContext , ExecutionStrategyParameters parameters ) {
435
437
MergedField field = parameters .getField ();
436
438
GraphQLObjectType parentType = (GraphQLObjectType ) parameters .getExecutionStepInfo ().getUnwrappedNonNullType ();
437
439
GraphQLFieldDefinition fieldDef = getFieldDef (executionContext .getGraphQLSchema (), parentType , field .getSingleField ());
438
440
return fetchField (fieldDef , executionContext , parameters );
439
441
}
440
442
441
- private Object /* CompletableFuture<FetchedValue> | FetchedValue>*/
442
- fetchField (GraphQLFieldDefinition fieldDef , ExecutionContext executionContext , ExecutionStrategyParameters parameters ) {
443
+ @ DuckTyped ( shape = " CompletableFuture<FetchedValue> | FetchedValue" )
444
+ private Object fetchField (GraphQLFieldDefinition fieldDef , ExecutionContext executionContext , ExecutionStrategyParameters parameters ) {
443
445
444
446
if (incrementAndCheckMaxNodesExceeded (executionContext )) {
445
447
return new FetchedValue (null , Collections .emptyList (), null );
@@ -498,6 +500,11 @@ Async.CombinedBuilder<FieldValueInfo> getAsyncFieldValueInfo(
498
500
executionContext .getDataLoaderDispatcherStrategy ().fieldFetched (executionContext , parameters , dataFetcher , fetchedObject );
499
501
fetchCtx .onDispatched ();
500
502
fetchCtx .onFetchedValue (fetchedObject );
503
+ // if it's a subscription, leave any reactive objects alone
504
+ if (!executionContext .isSubscriptionOperation ()) {
505
+ // possible convert reactive objects into CompletableFutures
506
+ fetchedObject = ReactiveSupport .fetchedObject (fetchedObject );
507
+ }
501
508
if (fetchedObject instanceof CompletableFuture ) {
502
509
@ SuppressWarnings ("unchecked" )
503
510
CompletableFuture <Object > fetchedValue = (CompletableFuture <Object >) fetchedObject ;
@@ -737,8 +744,8 @@ private FieldValueInfo getFieldValueInfoForNull(ExecutionStrategyParameters para
737
744
*
738
745
* @throws NonNullableFieldWasNullException inside the {@link CompletableFuture} if a non-null field resolves to a null value
739
746
*/
740
- protected Object /* CompletableFuture<Object> | Object */
741
- completeValueForNull (ExecutionStrategyParameters parameters ) {
747
+ @ DuckTyped ( shape = " CompletableFuture<Object> | Object" )
748
+ protected Object completeValueForNull (ExecutionStrategyParameters parameters ) {
742
749
try {
743
750
return parameters .getNonNullFieldValidator ().validate (parameters , null );
744
751
} catch (Exception e ) {
@@ -876,8 +883,8 @@ protected <T> void handleValueException(CompletableFuture<T> overallResult, Thro
876
883
*
877
884
* @return a materialized scalar value or exceptionally completed {@link CompletableFuture} if there is a problem
878
885
*/
879
- protected Object /* CompletableFuture<Object> | Object */
880
- completeValueForScalar (ExecutionContext executionContext , ExecutionStrategyParameters parameters , GraphQLScalarType scalarType , Object result ) {
886
+ @ DuckTyped ( shape = " CompletableFuture<Object> | Object" )
887
+ protected Object completeValueForScalar (ExecutionContext executionContext , ExecutionStrategyParameters parameters , GraphQLScalarType scalarType , Object result ) {
881
888
Object serialized ;
882
889
try {
883
890
serialized = scalarType .getCoercing ().serialize (result , executionContext .getGraphQLContext (), executionContext .getLocale ());
@@ -903,8 +910,8 @@ protected <T> void handleValueException(CompletableFuture<T> overallResult, Thro
903
910
*
904
911
* @return a materialized enum value or exceptionally completed {@link CompletableFuture} if there is a problem
905
912
*/
906
- protected Object /* CompletableFuture<Object> | Object */
907
- completeValueForEnum (ExecutionContext executionContext , ExecutionStrategyParameters parameters , GraphQLEnumType enumType , Object result ) {
913
+ @ DuckTyped ( shape = " CompletableFuture<Object> | Object" )
914
+ protected Object completeValueForEnum (ExecutionContext executionContext , ExecutionStrategyParameters parameters , GraphQLEnumType enumType , Object result ) {
908
915
Object serialized ;
909
916
try {
910
917
serialized = enumType .serialize (result , executionContext .getGraphQLContext (), executionContext .getLocale ());
@@ -929,8 +936,8 @@ protected <T> void handleValueException(CompletableFuture<T> overallResult, Thro
929
936
*
930
937
* @return a {@link CompletableFuture} promise to a map of object field values or a materialized map of object field values
931
938
*/
932
- protected Object /* CompletableFuture<Map<String, Object>> | Map<String, Object> */
933
- completeValueForObject (ExecutionContext executionContext , ExecutionStrategyParameters parameters , GraphQLObjectType resolvedObjectType , Object result ) {
939
+ @ DuckTyped ( shape = " CompletableFuture<Map<String, Object>> | Map<String, Object>" )
940
+ protected Object completeValueForObject (ExecutionContext executionContext , ExecutionStrategyParameters parameters , GraphQLObjectType resolvedObjectType , Object result ) {
934
941
ExecutionStepInfo executionStepInfo = parameters .getExecutionStepInfo ();
935
942
936
943
FieldCollectorParameters collectorParameters = newParameters ()
@@ -1000,7 +1007,6 @@ private void handleTypeMismatchProblem(ExecutionContext context, ExecutionStrate
1000
1007
* if max nodes were exceeded for this request.
1001
1008
*
1002
1009
* @param executionContext the execution context in play
1003
- *
1004
1010
* @return true if max nodes were exceeded
1005
1011
*/
1006
1012
private boolean incrementAndCheckMaxNodesExceeded (ExecutionContext executionContext ) {
@@ -1053,7 +1059,6 @@ protected GraphQLFieldDefinition getFieldDef(GraphQLSchema schema, GraphQLObject
1053
1059
*
1054
1060
* @param e this indicates that a null value was returned for a non null field, which needs to cause the parent field
1055
1061
* to become null OR continue on as an exception
1056
- *
1057
1062
* @throws NonNullableFieldWasNullException if a non null field resolves to a null value
1058
1063
*/
1059
1064
protected void assertNonNullFieldPrecondition (NonNullableFieldWasNullException e ) throws NonNullableFieldWasNullException {
@@ -1167,4 +1172,6 @@ private static void addErrorsToRightContext(List<GraphQLError> errors, Execution
1167
1172
executionContext .addErrors (errors );
1168
1173
}
1169
1174
}
1175
+
1176
+
1170
1177
}
0 commit comments