Skip to content

Commit f3f5516

Browse files
committed
ContextDataFetcherDecorator support for DataFetcherResult
Closes gh-1143
1 parent 008a78d commit f3f5516

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

spring-graphql/src/main/java/org/springframework/graphql/execution/ContextDataFetcherDecorator.java

+25-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import graphql.ExecutionInput;
2222
import graphql.GraphQLContext;
2323
import graphql.TrivialDataFetcher;
24+
import graphql.execution.DataFetcherResult;
2425
import graphql.schema.DataFetcher;
2526
import graphql.schema.DataFetchingEnvironment;
2627
import graphql.schema.FieldCoordinates;
@@ -39,6 +40,7 @@
3940
import reactor.core.publisher.Mono;
4041

4142
import org.springframework.graphql.ExecutionGraphQlRequest;
43+
import org.springframework.lang.Nullable;
4244
import org.springframework.util.Assert;
4345

4446
/**
@@ -74,7 +76,6 @@ private ContextDataFetcherDecorator(
7476
}
7577

7678

77-
@SuppressWarnings("ReactiveStreamsUnusedPublisher")
7879
@Override
7980
public Object get(DataFetchingEnvironment env) throws Exception {
8081

@@ -83,10 +84,33 @@ public Object get(DataFetchingEnvironment env) throws Exception {
8384
ContextSnapshot snapshot = (env.getLocalContext() instanceof GraphQLContext localContext) ?
8485
snapshotFactory.captureFrom(graphQlContext, localContext) :
8586
snapshotFactory.captureFrom(graphQlContext);
87+
8688
Mono<Void> cancelledRequest = graphQlContext.get(ExecutionGraphQlRequest.CANCEL_PUBLISHER_CONTEXT_KEY);
8789

8890
Object value = snapshot.wrap(() -> this.delegate.get(env)).call();
8991

92+
if (value instanceof DataFetcherResult<?> dataFetcherResult) {
93+
Object adapted = updateValue(dataFetcherResult.getData(), snapshot, cancelledRequest);
94+
value = DataFetcherResult.newResult()
95+
.data(adapted)
96+
.errors(dataFetcherResult.getErrors())
97+
.localContext(dataFetcherResult.getLocalContext()).build();
98+
}
99+
else {
100+
value = updateValue(value, snapshot, cancelledRequest);
101+
}
102+
103+
return value;
104+
}
105+
106+
@SuppressWarnings("ReactiveStreamsUnusedPublisher")
107+
private @Nullable Object updateValue(
108+
@Nullable Object value, ContextSnapshot snapshot, @Nullable Mono<Void> cancelledRequest) {
109+
110+
if (value == null) {
111+
return null;
112+
}
113+
90114
if (this.subscription) {
91115
Flux<?> subscriptionResult = ReactiveAdapterRegistryHelper.toSubscriptionFlux(value)
92116
.onErrorResume((exception) -> {

spring-graphql/src/test/java/org/springframework/graphql/execution/ContextDataFetcherDecoratorTests.java

+27
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import graphql.GraphQLError;
3131
import graphql.GraphqlErrorBuilder;
3232
import graphql.TrivialDataFetcher;
33+
import graphql.execution.DataFetcherResult;
3334
import graphql.schema.DataFetcher;
3435
import graphql.schema.DataFetcherFactories;
3536
import graphql.schema.FieldCoordinates;
@@ -135,6 +136,32 @@ void fluxDataFetcherSubscription() throws Exception {
135136
.verifyComplete();
136137
}
137138

139+
@Test
140+
void fluxDataFetcherSubscriptionWithDataFetcherResult() throws Exception {
141+
GraphQL graphQl = GraphQlSetup.schemaContent(SCHEMA_CONTENT)
142+
.subscriptionFetcher("greetings", (env) -> {
143+
Flux<String> flux = Mono.delay(Duration.ofMillis(50))
144+
.flatMapMany((aLong) -> Flux.deferContextual((context) -> {
145+
String name = context.get("name");
146+
return Flux.just("Hi", "Bonjour", "Hola").map((s) -> s + " " + name);
147+
}));
148+
return DataFetcherResult.newResult().data(flux).build();
149+
})
150+
.toGraphQl();
151+
152+
ExecutionInput input = ExecutionInput.newExecutionInput().query("subscription { greetings }").build();
153+
input.getGraphQLContext().put("name", "007");
154+
155+
ExecutionResult executionResult = graphQl.executeAsync(input).get();
156+
157+
Flux<String> greetingsFlux = ResponseHelper.forSubscription(executionResult)
158+
.map(response -> response.toEntity("greetings", String.class));
159+
160+
StepVerifier.create(greetingsFlux)
161+
.expectNext("Hi 007", "Bonjour 007", "Hola 007")
162+
.verifyComplete();
163+
}
164+
138165
@Test
139166
void fluxDataFetcherSubscriptionThrowingException() throws Exception {
140167

0 commit comments

Comments
 (0)