Skip to content

Commit 50b794c

Browse files
committed
Minor refactoring in RequestInput
1 parent 76940c2 commit 50b794c

File tree

4 files changed

+60
-37
lines changed

4 files changed

+60
-37
lines changed

spring-graphql/src/main/java/org/springframework/graphql/RequestInput.java

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@
3232
import org.springframework.util.CollectionUtils;
3333

3434
/**
35-
* Common representation for GraphQL request input. This can be converted to
36-
* {@link ExecutionInput} via {@link #toExecutionInput(boolean)} and the
37-
* {@code ExecutionInput} further customized via
38-
* {@link #configureExecutionInput(BiFunction)}.
35+
* Common, server-side representation of GraphQL request input independent of
36+
* the underlying transport. This can be converted to {@link ExecutionInput}
37+
* via {@link #toExecutionInput()} while the resulting {@code ExecutionInput}
38+
* can be customized via {@link #configureExecutionInput(BiFunction)} callbacks.
3939
*
4040
* @author Rossen Stoyanchev
4141
* @author Brian Clozel
@@ -60,6 +60,7 @@ public class RequestInput {
6060
@Nullable
6161
private ExecutionId executionId;
6262

63+
6364
/**
6465
* Create an instance.
6566
* @param query the query, mutation, or subscription for the request
@@ -83,17 +84,37 @@ public RequestInput(
8384

8485

8586
/**
86-
* Return an identifier for the request. This id can be later propagated
87-
* as the {@link ExecutionId} if {@link #executionId(ExecutionId) none has been set}.
88-
* <p>For web transports, this identifier can be used to correlate
89-
* request and response messages on a multiplexed connection.
90-
* @return the request id.
87+
* Return the id for the request selected by the transport handler.
88+
* <ul>
89+
* <li>For Spring MVC, the id is generated via
90+
* {@link org.springframework.util.AlternativeJdkIdGenerator}, which is more
91+
* efficient than {@code UUID.randomUUID()}.
92+
* <li>For WebFlux the id is from the {@code ServerHttpRequest}, which is
93+
* useful to correlate to WebFlux log messages.
94+
* <li>For WebSocket, the id is from the {@code Subscribe} message of the
95+
* GraphQL over WebSocket protocol, which is useful to correlate to
96+
* WebSocket messages.
97+
* </ul>
98+
* <p> By default, the transport id becomes the
99+
* {@link ExecutionInput.Builder#executionId(ExecutionId) executionId} for
100+
* the GraphQL request. You can override this via
101+
* {@link #executionId(ExecutionId)} or by configuring an
102+
* {@link graphql.execution.ExecutionIdProvider} on {@link graphql.GraphQL}.
103+
* @return the request id
91104
* @see <a href="https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md">GraphQL over WebSocket Protocol</a>
92105
*/
93106
public String getId() {
94107
return this.id;
95108
}
96109

110+
/**
111+
* Return the {@code executionId} configured via {@link #executionId(ExecutionId)}.
112+
*/
113+
@Nullable
114+
public ExecutionId getExecutionId() {
115+
return this.executionId;
116+
}
117+
97118
/**
98119
* Return the query, mutation, or subscription for the request.
99120
* @return the query, a non-empty string.
@@ -129,8 +150,10 @@ public Locale getLocale() {
129150
}
130151

131152
/**
132-
* Set an {@link ExecutionId} to be used for the {@link ExecutionInput}
133-
* @param executionId the execution id to use with the {@link ExecutionInput}.
153+
* Configure the {@link ExecutionId} to use for the GraphQL request, which
154+
* is set on the {@link ExecutionInput}. This option overrides the
155+
* {@link #getId() id} selected by the transport handler.
156+
* @param executionId the execution id to set on the {@link ExecutionInput}.
134157
*/
135158
public void executionId(ExecutionId executionId) {
136159
Assert.notNull(executionId, "executionId should not be null");
@@ -154,26 +177,21 @@ public void configureExecutionInput(BiFunction<ExecutionInput, ExecutionInput.Bu
154177
* populated from {@link #getQuery()}, {@link #getOperationName()}, and
155178
* {@link #getVariables()}, and is then further customized through
156179
* {@link #configureExecutionInput(BiFunction)}.
157-
* @param useRequestId whether the {@link #getId()} should be used as a fallback for {@link ExecutionId}.
158180
* @return the execution input
159181
*/
160-
public ExecutionInput toExecutionInput(boolean useRequestId) {
182+
public ExecutionInput toExecutionInput() {
161183
ExecutionInput.Builder inputBuilder = ExecutionInput.newExecutionInput()
162184
.query(this.query)
163185
.operationName(this.operationName)
164186
.variables(this.variables)
165-
.locale(this.locale);
166-
if (this.executionId != null) {
167-
inputBuilder.executionId(this.executionId);
168-
}
169-
else if (useRequestId) {
170-
inputBuilder.executionId(ExecutionId.from(this.id));
171-
}
187+
.locale(this.locale)
188+
.executionId(this.executionId != null ? this.executionId : ExecutionId.from(this.id));
189+
172190
ExecutionInput executionInput = inputBuilder.build();
173191

174192
for (BiFunction<ExecutionInput, ExecutionInput.Builder, ExecutionInput> configurer : this.executionInputConfigurers) {
175193
ExecutionInput current = executionInput;
176-
executionInput = executionInput.transform((builder) -> configurer.apply(current, builder));
194+
executionInput = executionInput.transform(builder -> configurer.apply(current, builder));
177195
}
178196

179197
return executionInput;

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.util.ArrayList;
2020
import java.util.List;
21+
import java.util.function.BiFunction;
2122

2223
import graphql.ExecutionInput;
2324
import graphql.GraphQL;
@@ -39,16 +40,21 @@
3940
*/
4041
public class ExecutionGraphQlService implements GraphQlService {
4142

43+
private static final BiFunction<ExecutionInput, ExecutionInput.Builder, ExecutionInput> RESET_EXECUTION_ID_CONFIGURER =
44+
(executionInput, builder) -> builder.executionId(null).build();
45+
46+
4247
private final GraphQlSource graphQlSource;
4348

4449
private final List<DataLoaderRegistrar> dataLoaderRegistrars = new ArrayList<>();
4550

46-
private final boolean hasDefaultExecutionIdProvider;
51+
private final boolean isDefaultExecutionIdProvider;
4752

4853

4954
public ExecutionGraphQlService(GraphQlSource graphQlSource) {
5055
this.graphQlSource = graphQlSource;
51-
this.hasDefaultExecutionIdProvider = ExecutionIdProvider.DEFAULT_EXECUTION_ID_PROVIDER == graphQlSource.graphQl().getIdProvider();
56+
this.isDefaultExecutionIdProvider =
57+
(graphQlSource.graphQl().getIdProvider() == ExecutionIdProvider.DEFAULT_EXECUTION_ID_PROVIDER);
5258
}
5359

5460

@@ -65,7 +71,10 @@ public void addDataLoaderRegistrar(DataLoaderRegistrar registrar) {
6571
@Override
6672
public final Mono<RequestOutput> execute(RequestInput requestInput) {
6773
return Mono.deferContextual((contextView) -> {
68-
ExecutionInput executionInput = requestInput.toExecutionInput(this.hasDefaultExecutionIdProvider);
74+
if (!this.isDefaultExecutionIdProvider && requestInput.getExecutionId() == null) {
75+
requestInput.configureExecutionInput(RESET_EXECUTION_ID_CONFIGURER);
76+
}
77+
ExecutionInput executionInput = requestInput.toExecutionInput();
6978
ReactorContextManager.setReactorContext(contextView, executionInput);
7079
ExecutionInput updatedExecutionInput = registerDataLoaders(executionInput);
7180
return Mono.fromFuture(this.graphQlSource.graphQl().executeAsync(updatedExecutionInput))

spring-graphql/src/test/java/org/springframework/graphql/RequestInputTests.java

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,19 @@
2828
*/
2929
class RequestInputTests {
3030

31-
private RequestInput requestInput = new RequestInput("greeting", "Greeting", null, null, "id");
31+
private final RequestInput requestInput = new RequestInput("greeting", "Greeting", null, null, "id");
3232

33-
@Test
34-
void shouldUseCustomExecutionIdIfPresent() {
35-
ExecutionId customId = ExecutionId.from("customId");
36-
this.requestInput.executionId(customId);
37-
assertThat(this.requestInput.toExecutionInput(true).getExecutionId()).isEqualTo(customId);
38-
assertThat(this.requestInput.toExecutionInput(false).getExecutionId()).isEqualTo(customId);
39-
}
4033

4134
@Test
42-
void executionIdShouldFallBackToRequestId() {
43-
assertThat(this.requestInput.toExecutionInput(true).getExecutionId()).isEqualTo(ExecutionId.from("id"));
35+
void shouldUseRequestId() {
36+
assertThat(this.requestInput.toExecutionInput().getExecutionId()).isEqualTo(ExecutionId.from("id"));
4437
}
4538

4639
@Test
47-
void executionIdShouldFallBackToProvider() {
48-
assertThat(this.requestInput.toExecutionInput(false).getExecutionId()).isNull();
40+
void shouldUseExecutionId() {
41+
ExecutionId customId = ExecutionId.from("customId");
42+
this.requestInput.executionId(customId);
43+
assertThat(this.requestInput.toExecutionInput().getExecutionId()).isEqualTo(customId);
4944
}
45+
5046
}

spring-graphql/src/test/java/org/springframework/graphql/web/WebInterceptorTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ void executionInputCustomization() {
7979

8080
WebGraphQlHandler handler = WebGraphQlHandler
8181
.builder((input) -> {
82-
actualName.set(input.toExecutionInput(true).getOperationName());
82+
actualName.set(input.toExecutionInput().getOperationName());
8383
return emptyExecutionResult(input);
8484
})
8585
.interceptor((webInput, next) -> {

0 commit comments

Comments
 (0)