32
32
import org .springframework .util .CollectionUtils ;
33
33
34
34
/**
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 .
39
39
*
40
40
* @author Rossen Stoyanchev
41
41
* @author Brian Clozel
@@ -60,6 +60,7 @@ public class RequestInput {
60
60
@ Nullable
61
61
private ExecutionId executionId ;
62
62
63
+
63
64
/**
64
65
* Create an instance.
65
66
* @param query the query, mutation, or subscription for the request
@@ -83,17 +84,37 @@ public RequestInput(
83
84
84
85
85
86
/**
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
91
104
* @see <a href="https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md">GraphQL over WebSocket Protocol</a>
92
105
*/
93
106
public String getId () {
94
107
return this .id ;
95
108
}
96
109
110
+ /**
111
+ * Return the {@code executionId} configured via {@link #executionId(ExecutionId)}.
112
+ */
113
+ @ Nullable
114
+ public ExecutionId getExecutionId () {
115
+ return this .executionId ;
116
+ }
117
+
97
118
/**
98
119
* Return the query, mutation, or subscription for the request.
99
120
* @return the query, a non-empty string.
@@ -129,8 +150,10 @@ public Locale getLocale() {
129
150
}
130
151
131
152
/**
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}.
134
157
*/
135
158
public void executionId (ExecutionId executionId ) {
136
159
Assert .notNull (executionId , "executionId should not be null" );
@@ -154,26 +177,21 @@ public void configureExecutionInput(BiFunction<ExecutionInput, ExecutionInput.Bu
154
177
* populated from {@link #getQuery()}, {@link #getOperationName()}, and
155
178
* {@link #getVariables()}, and is then further customized through
156
179
* {@link #configureExecutionInput(BiFunction)}.
157
- * @param useRequestId whether the {@link #getId()} should be used as a fallback for {@link ExecutionId}.
158
180
* @return the execution input
159
181
*/
160
- public ExecutionInput toExecutionInput (boolean useRequestId ) {
182
+ public ExecutionInput toExecutionInput () {
161
183
ExecutionInput .Builder inputBuilder = ExecutionInput .newExecutionInput ()
162
184
.query (this .query )
163
185
.operationName (this .operationName )
164
186
.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
+
172
190
ExecutionInput executionInput = inputBuilder .build ();
173
191
174
192
for (BiFunction <ExecutionInput , ExecutionInput .Builder , ExecutionInput > configurer : this .executionInputConfigurers ) {
175
193
ExecutionInput current = executionInput ;
176
- executionInput = executionInput .transform (( builder ) -> configurer .apply (current , builder ));
194
+ executionInput = executionInput .transform (builder -> configurer .apply (current , builder ));
177
195
}
178
196
179
197
return executionInput ;
0 commit comments