From ac6fbf9f8b1c9d95451d7c018b628a25d7632d75 Mon Sep 17 00:00:00 2001 From: bbaker Date: Mon, 28 Apr 2025 21:48:21 +1000 Subject: [PATCH 1/2] ExecutionStrategyParameters now has a direct transform without a Builder --- .../AsyncSerialExecutionStrategy.java | 6 ++-- .../graphql/execution/ExecutionStrategy.java | 34 +++++++------------ .../ExecutionStrategyParameters.java | 26 ++++++++++++++ .../SubscriptionExecutionStrategy.java | 2 +- .../incremental/DeferredExecutionSupport.java | 4 ++- 5 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/main/java/graphql/execution/AsyncSerialExecutionStrategy.java b/src/main/java/graphql/execution/AsyncSerialExecutionStrategy.java index 545d0fb0a9..98c6ce478b 100644 --- a/src/main/java/graphql/execution/AsyncSerialExecutionStrategy.java +++ b/src/main/java/graphql/execution/AsyncSerialExecutionStrategy.java @@ -52,11 +52,9 @@ public CompletableFuture execute(ExecutionContext executionCont CompletableFuture> resultsFuture = Async.eachSequentially(fieldNames, (fieldName, prevResults) -> { MergedField currentField = fields.getSubField(fieldName); ResultPath fieldPath = parameters.getPath().segment(mkNameForPath(currentField)); - ExecutionStrategyParameters newParameters = parameters - .transform(builder -> builder.field(currentField).path(fieldPath)); + ExecutionStrategyParameters newParameters = parameters.transform(currentField, fieldPath); - Object resolveSerialField = resolveSerialField(executionContext, dataLoaderDispatcherStrategy, newParameters); - return resolveSerialField; + return resolveSerialField(executionContext, dataLoaderDispatcherStrategy, newParameters); }); CompletableFuture overallResult = new CompletableFuture<>(); diff --git a/src/main/java/graphql/execution/ExecutionStrategy.java b/src/main/java/graphql/execution/ExecutionStrategy.java index f9370d1e91..b9c33c5118 100644 --- a/src/main/java/graphql/execution/ExecutionStrategy.java +++ b/src/main/java/graphql/execution/ExecutionStrategy.java @@ -329,8 +329,7 @@ DeferredExecutionSupport createDeferredExecutionSupport(ExecutionContext executi MergedField currentField = fields.getSubField(fieldName); ResultPath fieldPath = parameters.getPath().segment(mkNameForPath(currentField)); - ExecutionStrategyParameters newParameters = parameters - .transform(builder -> builder.field(currentField).path(fieldPath).parent(parameters)); + ExecutionStrategyParameters newParameters = parameters.transform(currentField, fieldPath, parameters); if (!deferredExecutionSupport.isDeferredField(currentField)) { Object fieldValueInfo = resolveFieldWithInfo(executionContext, newParameters); @@ -627,12 +626,10 @@ private FieldValueInfo completeField(GraphQLFieldDefinition fieldDef, ExecutionC NonNullableFieldValidator nonNullableFieldValidator = new NonNullableFieldValidator(executionContext, executionStepInfo); - ExecutionStrategyParameters newParameters = parameters.transform(builder -> - builder.executionStepInfo(executionStepInfo) - .source(fetchedValue.getFetchedValue()) - .localContext(fetchedValue.getLocalContext()) - .nonNullFieldValidator(nonNullableFieldValidator) - ); + ExecutionStrategyParameters newParameters = parameters.transform(executionStepInfo, + nonNullableFieldValidator, + fetchedValue.getLocalContext(), + fetchedValue.getFetchedValue()); FieldValueInfo fieldValueInfo = completeValue(executionContext, newParameters); @@ -790,13 +787,10 @@ protected FieldValueInfo completeValueForList(ExecutionContext executionContext, FetchedValue value = unboxPossibleDataFetcherResult(executionContext, parameters, item); - ExecutionStrategyParameters newParameters = parameters.transform(builder -> - builder.executionStepInfo(stepInfoForListElement) - .nonNullFieldValidator(nonNullableFieldValidator) - .localContext(value.getLocalContext()) - .path(indexedPath) - .source(value.getFetchedValue()) - ); + ExecutionStrategyParameters newParameters = parameters.transform(stepInfoForListElement, + nonNullableFieldValidator, indexedPath, + value.getLocalContext(), value.getFetchedValue()); + fieldValueInfos.add(completeValue(executionContext, newParameters)); index++; } @@ -936,12 +930,10 @@ protected Object completeValueForObject(ExecutionContext executionContext, Execu ExecutionStepInfo newExecutionStepInfo = executionStepInfo.changeTypeWithPreservedNonNull(resolvedObjectType); NonNullableFieldValidator nonNullableFieldValidator = new NonNullableFieldValidator(executionContext, newExecutionStepInfo); - ExecutionStrategyParameters newParameters = parameters.transform(builder -> - builder.executionStepInfo(newExecutionStepInfo) - .fields(subFields) - .nonNullFieldValidator(nonNullableFieldValidator) - .source(result) - ); + ExecutionStrategyParameters newParameters = parameters.transform(newExecutionStepInfo, + nonNullableFieldValidator, + subFields, + result); // Calling this from the executionContext to ensure we shift back from mutation strategy to the query strategy. return executionContext.getQueryStrategy().executeObject(executionContext, newParameters); diff --git a/src/main/java/graphql/execution/ExecutionStrategyParameters.java b/src/main/java/graphql/execution/ExecutionStrategyParameters.java index c2e46b9a67..a0f4aa37b9 100644 --- a/src/main/java/graphql/execution/ExecutionStrategyParameters.java +++ b/src/main/java/graphql/execution/ExecutionStrategyParameters.java @@ -1,5 +1,6 @@ package graphql.execution; +import graphql.Internal; import graphql.PublicApi; import graphql.execution.incremental.DeferredCallContext; import org.jspecify.annotations.Nullable; @@ -115,6 +116,31 @@ public MergedField getField() { return currentField; } + @Internal + ExecutionStrategyParameters transform(MergedField currentField, ResultPath path) { + return new ExecutionStrategyParameters(executionStepInfo, source, localContext, fields, nonNullableFieldValidator, path, currentField, parent, deferredCallContext); + } + + @Internal + ExecutionStrategyParameters transform(ExecutionStepInfo executionStepInfo, NonNullableFieldValidator nonNullableFieldValidator, MergedSelectionSet fields, Object source) { + return new ExecutionStrategyParameters(executionStepInfo, source, localContext, fields, nonNullableFieldValidator, path, currentField, parent, deferredCallContext); + } + + @Internal + ExecutionStrategyParameters transform(ExecutionStepInfo executionStepInfo, NonNullableFieldValidator nonNullableFieldValidator, ResultPath path, Object localContext, Object source) { + return new ExecutionStrategyParameters(executionStepInfo, source, localContext, fields, nonNullableFieldValidator, path, currentField, parent, deferredCallContext); + } + + @Internal + ExecutionStrategyParameters transform(ExecutionStepInfo executionStepInfo, NonNullableFieldValidator nonNullableFieldValidator, Object localContext, Object source) { + return new ExecutionStrategyParameters(executionStepInfo, source, localContext, fields, nonNullableFieldValidator, path, currentField, parent, deferredCallContext); + } + + @Internal + ExecutionStrategyParameters transform(MergedField currentField, ResultPath path, ExecutionStrategyParameters parent) { + return new ExecutionStrategyParameters(executionStepInfo, source, localContext, fields, nonNullableFieldValidator, path, currentField, parent, deferredCallContext); + } + public ExecutionStrategyParameters transform(Consumer builderConsumer) { Builder builder = newParameters(this); builderConsumer.accept(builder); diff --git a/src/main/java/graphql/execution/SubscriptionExecutionStrategy.java b/src/main/java/graphql/execution/SubscriptionExecutionStrategy.java index 464f725946..e8f0763c0a 100644 --- a/src/main/java/graphql/execution/SubscriptionExecutionStrategy.java +++ b/src/main/java/graphql/execution/SubscriptionExecutionStrategy.java @@ -184,7 +184,7 @@ private ExecutionStrategyParameters firstFieldOfSubscriptionSelection(ExecutionS MergedField firstField = fields.getSubField(fields.getKeys().get(0)); ResultPath fieldPath = parameters.getPath().segment(mkNameForPath(firstField.getSingleField())); - return parameters.transform(builder -> builder.field(firstField).path(fieldPath)); + return parameters.transform(firstField,fieldPath); } private ExecutionStepInfo createSubscribedFieldStepInfo(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { diff --git a/src/main/java/graphql/execution/incremental/DeferredExecutionSupport.java b/src/main/java/graphql/execution/incremental/DeferredExecutionSupport.java index 3b8e7efe8a..5047ee5602 100644 --- a/src/main/java/graphql/execution/incremental/DeferredExecutionSupport.java +++ b/src/main/java/graphql/execution/incremental/DeferredExecutionSupport.java @@ -11,6 +11,7 @@ import graphql.execution.FieldValueInfo; import graphql.execution.MergedField; import graphql.execution.MergedSelectionSet; +import graphql.execution.ResultPath; import graphql.execution.instrumentation.Instrumentation; import graphql.incremental.IncrementalPayload; import graphql.util.FpKit; @@ -139,10 +140,11 @@ private Supplier { MergedSelectionSet mergedSelectionSet = MergedSelectionSet.newMergedSelectionSet().subFields(fields).build(); + ResultPath path = parameters.getPath().segment(currentField.getResultKey()); builder.deferredCallContext(deferredCallContext) .field(currentField) .fields(mergedSelectionSet) - .path(parameters.getPath().segment(currentField.getResultKey())) + .path(path) .parent(null); // this is a break in the parent -> child chain - it's a new start effectively } ); From 3790a10f2d92cc1975f1c9311189a2bc4d38889b Mon Sep 17 00:00:00 2001 From: bbaker Date: Mon, 28 Apr 2025 21:51:19 +1000 Subject: [PATCH 2/2] ExecutionStrategyParameters now has a direct transform without a Builder - tweak --- .../ExecutionStrategyParameters.java | 73 ++++++++++++++++--- 1 file changed, 63 insertions(+), 10 deletions(-) diff --git a/src/main/java/graphql/execution/ExecutionStrategyParameters.java b/src/main/java/graphql/execution/ExecutionStrategyParameters.java index a0f4aa37b9..116a50751d 100644 --- a/src/main/java/graphql/execution/ExecutionStrategyParameters.java +++ b/src/main/java/graphql/execution/ExecutionStrategyParameters.java @@ -117,28 +117,81 @@ public MergedField getField() { } @Internal - ExecutionStrategyParameters transform(MergedField currentField, ResultPath path) { - return new ExecutionStrategyParameters(executionStepInfo, source, localContext, fields, nonNullableFieldValidator, path, currentField, parent, deferredCallContext); + ExecutionStrategyParameters transform(MergedField currentField, + ResultPath path) { + return new ExecutionStrategyParameters(executionStepInfo, + source, + localContext, + fields, + nonNullableFieldValidator, + path, + currentField, + parent, + deferredCallContext); } @Internal - ExecutionStrategyParameters transform(ExecutionStepInfo executionStepInfo, NonNullableFieldValidator nonNullableFieldValidator, MergedSelectionSet fields, Object source) { - return new ExecutionStrategyParameters(executionStepInfo, source, localContext, fields, nonNullableFieldValidator, path, currentField, parent, deferredCallContext); + ExecutionStrategyParameters transform(ExecutionStepInfo executionStepInfo, + NonNullableFieldValidator nonNullableFieldValidator, + MergedSelectionSet fields, + Object source) { + return new ExecutionStrategyParameters(executionStepInfo, + source, + localContext, + fields, + nonNullableFieldValidator, + path, + currentField, + parent, + deferredCallContext); } @Internal - ExecutionStrategyParameters transform(ExecutionStepInfo executionStepInfo, NonNullableFieldValidator nonNullableFieldValidator, ResultPath path, Object localContext, Object source) { - return new ExecutionStrategyParameters(executionStepInfo, source, localContext, fields, nonNullableFieldValidator, path, currentField, parent, deferredCallContext); + ExecutionStrategyParameters transform(ExecutionStepInfo executionStepInfo, + NonNullableFieldValidator nonNullableFieldValidator, + ResultPath path, + Object localContext, + Object source) { + return new ExecutionStrategyParameters(executionStepInfo, + source, + localContext, + fields, + nonNullableFieldValidator, + path, + currentField, + parent, + deferredCallContext); } @Internal - ExecutionStrategyParameters transform(ExecutionStepInfo executionStepInfo, NonNullableFieldValidator nonNullableFieldValidator, Object localContext, Object source) { - return new ExecutionStrategyParameters(executionStepInfo, source, localContext, fields, nonNullableFieldValidator, path, currentField, parent, deferredCallContext); + ExecutionStrategyParameters transform(ExecutionStepInfo executionStepInfo, + NonNullableFieldValidator nonNullableFieldValidator, + Object localContext, + Object source) { + return new ExecutionStrategyParameters(executionStepInfo, + source, + localContext, + fields, + nonNullableFieldValidator, + path, + currentField, + parent, + deferredCallContext); } @Internal - ExecutionStrategyParameters transform(MergedField currentField, ResultPath path, ExecutionStrategyParameters parent) { - return new ExecutionStrategyParameters(executionStepInfo, source, localContext, fields, nonNullableFieldValidator, path, currentField, parent, deferredCallContext); + ExecutionStrategyParameters transform(MergedField currentField, + ResultPath path, + ExecutionStrategyParameters parent) { + return new ExecutionStrategyParameters(executionStepInfo, + source, + localContext, + fields, + nonNullableFieldValidator, + path, + currentField, + parent, + deferredCallContext); } public ExecutionStrategyParameters transform(Consumer builderConsumer) {