Skip to content

Commit 8b830b1

Browse files
committed
Ability to provide CacheControl instance via ExecutionInput
1 parent 858250e commit 8b830b1

10 files changed

Lines changed: 80 additions & 8 deletions

‎src/main/java/graphql/ExecutionInput.java‎

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package graphql;
22

3+
import graphql.cachecontrol.CacheControl;
34
import org.dataloader.DataLoaderRegistry;
45

56
import java.util.Collections;
@@ -20,20 +21,22 @@ public class ExecutionInput {
2021
private final Object root;
2122
private final Map<String, Object> variables;
2223
private final DataLoaderRegistry dataLoaderRegistry;
24+
private final CacheControl cacheControl;
2325

2426

2527
public ExecutionInput(String query, String operationName, Object context, Object root, Map<String, Object> variables) {
26-
this(query, operationName, context, root, variables, new DataLoaderRegistry());
28+
this(query, operationName, context, root, variables, new DataLoaderRegistry(), null);
2729
}
2830

2931
@Internal
30-
private ExecutionInput(String query, String operationName, Object context, Object root, Map<String, Object> variables, DataLoaderRegistry dataLoaderRegistry) {
32+
private ExecutionInput(String query, String operationName, Object context, Object root, Map<String, Object> variables, DataLoaderRegistry dataLoaderRegistry, CacheControl cacheControl) {
3133
this.query = query;
3234
this.operationName = operationName;
3335
this.context = context;
3436
this.root = root;
3537
this.variables = variables;
3638
this.dataLoaderRegistry = dataLoaderRegistry;
39+
this.cacheControl = cacheControl;
3740
}
3841

3942
/**
@@ -78,6 +81,13 @@ public DataLoaderRegistry getDataLoaderRegistry() {
7881
return dataLoaderRegistry;
7982
}
8083

84+
/**
85+
* @return the cache control helper associated with this execution
86+
*/
87+
public CacheControl getCacheControl() {
88+
return cacheControl;
89+
}
90+
8191
/**
8292
* This helps you transform the current ExecutionInput object into another one by starting a builder with all
8393
* the current values and allows you to transform it how you want.
@@ -93,6 +103,7 @@ public ExecutionInput transform(Consumer<Builder> builderConsumer) {
93103
.context(this.context)
94104
.root(this.root)
95105
.dataLoaderRegistry(this.dataLoaderRegistry)
106+
.cacheControl(this.cacheControl)
96107
.variables(this.variables);
97108

98109
builderConsumer.accept(builder);
@@ -139,6 +150,7 @@ public static class Builder {
139150
private Object root;
140151
private Map<String, Object> variables = Collections.emptyMap();
141152
private DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry();
153+
private CacheControl cacheControl;
142154

143155
public Builder query(String query) {
144156
this.query = query;
@@ -196,8 +208,13 @@ public Builder dataLoaderRegistry(DataLoaderRegistry dataLoaderRegistry) {
196208
return this;
197209
}
198210

211+
public Builder cacheControl(CacheControl cacheControl) {
212+
this.cacheControl = cacheControl;
213+
return this;
214+
}
215+
199216
public ExecutionInput build() {
200-
return new ExecutionInput(query, operationName, context, root, variables, dataLoaderRegistry);
217+
return new ExecutionInput(query, operationName, context, root, variables, dataLoaderRegistry, cacheControl);
201218
}
202219
}
203220
}

‎src/main/java/graphql/execution/Execution.java‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ public CompletableFuture<ExecutionResult> execute(Document document, GraphQLSche
9090
.document(document)
9191
.operationDefinition(operationDefinition)
9292
.dataLoaderRegistry(executionInput.getDataLoaderRegistry())
93+
.cacheControl(executionInput.getCacheControl())
9394
.build();
9495

9596

‎src/main/java/graphql/execution/ExecutionContext.java‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import graphql.GraphQLError;
55
import graphql.Internal;
66
import graphql.PublicApi;
7+
import graphql.cachecontrol.CacheControl;
78
import graphql.execution.defer.DeferSupport;
89
import graphql.execution.instrumentation.Instrumentation;
910
import graphql.execution.instrumentation.InstrumentationState;
@@ -38,10 +39,11 @@ public class ExecutionContext {
3839
private final Instrumentation instrumentation;
3940
private final List<GraphQLError> errors = new CopyOnWriteArrayList<>();
4041
private final DataLoaderRegistry dataLoaderRegistry;
42+
private final CacheControl cacheControl;
4143
private final DeferSupport deferSupport = new DeferSupport();
4244

4345
@Internal
44-
ExecutionContext(Instrumentation instrumentation, ExecutionId executionId, GraphQLSchema graphQLSchema, InstrumentationState instrumentationState, ExecutionStrategy queryStrategy, ExecutionStrategy mutationStrategy, ExecutionStrategy subscriptionStrategy, Map<String, FragmentDefinition> fragmentsByName, Document document, OperationDefinition operationDefinition, Map<String, Object> variables, Object context, Object root, DataLoaderRegistry dataLoaderRegistry, List<GraphQLError> startingErrors) {
46+
ExecutionContext(Instrumentation instrumentation, ExecutionId executionId, GraphQLSchema graphQLSchema, InstrumentationState instrumentationState, ExecutionStrategy queryStrategy, ExecutionStrategy mutationStrategy, ExecutionStrategy subscriptionStrategy, Map<String, FragmentDefinition> fragmentsByName, Document document, OperationDefinition operationDefinition, Map<String, Object> variables, Object context, Object root, DataLoaderRegistry dataLoaderRegistry, CacheControl cacheControl, List<GraphQLError> startingErrors) {
4547
this.graphQLSchema = graphQLSchema;
4648
this.executionId = executionId;
4749
this.instrumentationState = instrumentationState;
@@ -56,6 +58,7 @@ public class ExecutionContext {
5658
this.root = root;
5759
this.instrumentation = instrumentation;
5860
this.dataLoaderRegistry = dataLoaderRegistry;
61+
this.cacheControl = cacheControl;
5962
this.errors.addAll(startingErrors);
6063
}
6164

@@ -109,6 +112,10 @@ public DataLoaderRegistry getDataLoaderRegistry() {
109112
return dataLoaderRegistry;
110113
}
111114

115+
public CacheControl getCacheControl() {
116+
return cacheControl;
117+
}
118+
112119
/**
113120
* This method will only put one error per field path.
114121
*

‎src/main/java/graphql/execution/ExecutionContextBuilder.java‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import graphql.GraphQLError;
44
import graphql.Internal;
55
import graphql.PublicApi;
6+
import graphql.cachecontrol.CacheControl;
67
import graphql.execution.instrumentation.Instrumentation;
78
import graphql.execution.instrumentation.InstrumentationState;
89
import graphql.language.Document;
@@ -36,6 +37,7 @@ public class ExecutionContextBuilder {
3637
private Map<String, Object> variables = new LinkedHashMap<>();
3738
private Map<String, FragmentDefinition> fragmentsByName = new LinkedHashMap<>();
3839
private DataLoaderRegistry dataLoaderRegistry;
40+
private CacheControl cacheControl;
3941
private List<GraphQLError> errors = new ArrayList<>();
4042

4143
/**
@@ -76,6 +78,7 @@ public ExecutionContextBuilder() {
7678
variables = new HashMap<>(other.getVariables());
7779
fragmentsByName = new HashMap<>(other.getFragmentsByName());
7880
dataLoaderRegistry = other.getDataLoaderRegistry();
81+
cacheControl = other.getCacheControl();
7982
errors = new ArrayList<>(other.getErrors());
8083
}
8184

@@ -150,6 +153,11 @@ public ExecutionContextBuilder dataLoaderRegistry(DataLoaderRegistry dataLoaderR
150153
return this;
151154
}
152155

156+
public ExecutionContextBuilder cacheControl(CacheControl cacheControl) {
157+
this.cacheControl = cacheControl;
158+
return this;
159+
}
160+
153161
public ExecutionContext build() {
154162
// preconditions
155163
assertNotNull(executionId, "You must provide a query identifier");
@@ -168,7 +176,9 @@ public ExecutionContext build() {
168176
variables,
169177
context,
170178
root,
171-
dataLoaderRegistry, errors
179+
dataLoaderRegistry,
180+
cacheControl,
181+
errors
172182
);
173183
}
174184
}

‎src/main/java/graphql/schema/DataFetchingEnvironment.java‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package graphql.schema;
22

33
import graphql.PublicApi;
4+
import graphql.cachecontrol.CacheControl;
45
import graphql.execution.ExecutionId;
56
import graphql.execution.ExecutionStepInfo;
67
import graphql.execution.MergedField;
@@ -192,6 +193,11 @@ public interface DataFetchingEnvironment {
192193
*/
193194
<K, V> DataLoader<K, V> getDataLoader(String dataLoaderName);
194195

196+
/**
197+
* @return the current {@link CacheControl} instance used to add cache hints to the response
198+
*/
199+
CacheControl getCacheControl();
200+
195201
/**
196202
* @return the current operation that is being executed
197203
*/

‎src/main/java/graphql/schema/DataFetchingEnvironmentImpl.java‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33

44
import graphql.Internal;
5+
import graphql.cachecontrol.CacheControl;
56
import graphql.execution.ExecutionContext;
67
import graphql.execution.ExecutionId;
78
import graphql.execution.ExecutionStepInfo;
@@ -36,6 +37,7 @@ public class DataFetchingEnvironmentImpl implements DataFetchingEnvironment {
3637
private final DataFetchingFieldSelectionSet selectionSet;
3738
private final ExecutionStepInfo executionStepInfo;
3839
private final DataLoaderRegistry dataLoaderRegistry;
40+
private final CacheControl cacheControl;
3941
private final OperationDefinition operationDefinition;
4042
private final Document document;
4143
private final Map<String, Object> variables;
@@ -56,6 +58,7 @@ private DataFetchingEnvironmentImpl(Builder builder) {
5658
this.selectionSet = builder.selectionSet;
5759
this.executionStepInfo = builder.executionStepInfo;
5860
this.dataLoaderRegistry = builder.dataLoaderRegistry;
61+
this.cacheControl = builder.cacheControl;
5962
this.operationDefinition = builder.operationDefinition;
6063
this.document = builder.document;
6164
this.variables = builder.variables;
@@ -156,6 +159,11 @@ public <K, V> DataLoader<K, V> getDataLoader(String dataLoaderName) {
156159
return dataLoaderRegistry.getDataLoader(dataLoaderName);
157160
}
158161

162+
@Override
163+
public CacheControl getCacheControl() {
164+
return cacheControl;
165+
}
166+
159167
@Override
160168
public OperationDefinition getOperationDefinition() {
161169
return operationDefinition;
@@ -196,6 +204,7 @@ public static Builder newDataFetchingEnvironment(ExecutionContext executionConte
196204
.graphQLSchema(executionContext.getGraphQLSchema())
197205
.fragmentsByName(executionContext.getFragmentsByName())
198206
.dataLoaderRegistry(executionContext.getDataLoaderRegistry())
207+
.cacheControl(executionContext.getCacheControl())
199208
.document(executionContext.getDocument())
200209
.operationDefinition(executionContext.getOperationDefinition())
201210
.variables(executionContext.getVariables())
@@ -217,6 +226,7 @@ public static class Builder {
217226
private DataFetchingFieldSelectionSet selectionSet;
218227
private ExecutionStepInfo executionStepInfo;
219228
private DataLoaderRegistry dataLoaderRegistry;
229+
private CacheControl cacheControl;
220230
private OperationDefinition operationDefinition;
221231
private Document document;
222232
private final Map<String, Object> arguments = new LinkedHashMap<>();
@@ -239,6 +249,7 @@ public Builder(DataFetchingEnvironmentImpl env) {
239249
this.selectionSet = env.selectionSet;
240250
this.executionStepInfo = env.executionStepInfo;
241251
this.dataLoaderRegistry = env.dataLoaderRegistry;
252+
this.cacheControl = env.cacheControl;
242253
this.operationDefinition = env.operationDefinition;
243254
this.document = env.document;
244255
this.variables.putAll(env.variables);
@@ -322,6 +333,11 @@ public Builder dataLoaderRegistry(DataLoaderRegistry dataLoaderRegistry) {
322333
return this;
323334
}
324335

336+
public Builder cacheControl(CacheControl cacheControl) {
337+
this.cacheControl = cacheControl;
338+
return this;
339+
}
340+
325341
public Builder operationDefinition(OperationDefinition operationDefinition) {
326342
this.operationDefinition = operationDefinition;
327343
return this;

‎src/test/groovy/graphql/ExecutionInputTest.groovy‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package graphql
22

3+
import graphql.cachecontrol.CacheControl
34
import org.dataloader.DataLoaderRegistry
45
import spock.lang.Specification
56

@@ -9,6 +10,7 @@ class ExecutionInputTest extends Specification {
910

1011
def query = "query { hello }"
1112
def registry = new DataLoaderRegistry()
13+
def cacheControl = CacheControl.newCacheControl()
1214
def root = "root"
1315
def context = "context"
1416
def variables = [key: "value"]
@@ -17,6 +19,7 @@ class ExecutionInputTest extends Specification {
1719
when:
1820
def executionInput = ExecutionInput.newExecutionInput().query(query)
1921
.dataLoaderRegistry(registry)
22+
.cacheControl(cacheControl)
2023
.variables(variables)
2124
.root(root)
2225
.context(context)
@@ -26,6 +29,7 @@ class ExecutionInputTest extends Specification {
2629
executionInput.root == root
2730
executionInput.variables == variables
2831
executionInput.dataLoaderRegistry == registry
32+
executionInput.cacheControl == cacheControl
2933
executionInput.query == query
3034
}
3135

@@ -49,6 +53,7 @@ class ExecutionInputTest extends Specification {
4953
when:
5054
def executionInputOld = ExecutionInput.newExecutionInput().query(query)
5155
.dataLoaderRegistry(registry)
56+
.cacheControl(cacheControl)
5257
.variables(variables)
5358
.root(root)
5459
.context(context)
@@ -60,6 +65,7 @@ class ExecutionInputTest extends Specification {
6065
executionInput.root == root
6166
executionInput.variables == variables
6267
executionInput.dataLoaderRegistry == registry
68+
executionInput.cacheControl == cacheControl
6369
executionInput.query == "new query"
6470
}
6571

‎src/test/groovy/graphql/execution/ExecutionContextBuilderTest.groovy‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package graphql.execution
22

3+
import graphql.cachecontrol.CacheControl
34
import graphql.execution.instrumentation.Instrumentation
45
import graphql.language.Document
56
import graphql.language.FragmentDefinition
@@ -53,7 +54,10 @@ class ExecutionContextBuilderTest extends Specification {
5354
executionContextBuilder.variables([var: 'value'])
5455

5556
def dataLoaderRegistry = new DataLoaderRegistry()
56-
executionContextBuilder.dataLoaderRegistry(dataLoaderRegistry);
57+
executionContextBuilder.dataLoaderRegistry(dataLoaderRegistry)
58+
59+
def cacheControl = CacheControl.newCacheControl()
60+
executionContextBuilder.cacheControl(cacheControl)
5761

5862
when:
5963
def executionContext = executionContextBuilder.build()
@@ -71,5 +75,6 @@ class ExecutionContextBuilderTest extends Specification {
7175
executionContext.getFragmentsByName() == [MyFragment: fragment]
7276
executionContext.operationDefinition == operation
7377
executionContext.dataLoaderRegistry == dataLoaderRegistry
78+
executionContext.cacheControl == cacheControl
7479
}
7580
}

‎src/test/groovy/graphql/execution/ExecutionStrategyTest.groovy‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class ExecutionStrategyTest extends Specification {
6363
new ExecutionContext(SimpleInstrumentation.INSTANCE, executionId, schema ?: StarWarsSchema.starWarsSchema, null,
6464
executionStrategy, executionStrategy, executionStrategy,
6565
null, null, null,
66-
variables, "context", "root", new DataLoaderRegistry(), Collections.emptyList())
66+
variables, "context", "root", new DataLoaderRegistry(), null, Collections.emptyList())
6767
}
6868

6969
@SuppressWarnings("GroovyAssignabilityCheck")

‎src/test/groovy/graphql/schema/DataFetchingEnvironmentImplTest.groovy‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package graphql.schema
22

3-
3+
import graphql.cachecontrol.CacheControl
44
import graphql.execution.ExecutionId
55
import graphql.execution.ExecutionStepInfo
66
import graphql.language.FragmentDefinition
@@ -30,6 +30,7 @@ class DataFetchingEnvironmentImplTest extends Specification {
3030
def fragmentByName = [frag: frag]
3131
def variables = [var: "able"]
3232
def dataLoaderRegistry = new DataLoaderRegistry().register("dataLoader", dataLoader)
33+
def cacheControl = CacheControl.newCacheControl()
3334

3435
def executionContext = newExecutionContextBuilder()
3536
.root("root")
@@ -41,6 +42,7 @@ class DataFetchingEnvironmentImplTest extends Specification {
4142
.graphQLSchema(starWarsSchema)
4243
.fragmentsByName(fragmentByName)
4344
.dataLoaderRegistry(dataLoaderRegistry)
45+
.cacheControl(cacheControl)
4446
.build()
4547

4648

@@ -92,6 +94,7 @@ class DataFetchingEnvironmentImplTest extends Specification {
9294
.document(document)
9395
.variables(variables)
9496
.dataLoaderRegistry(dataLoaderRegistry)
97+
.cacheControl(cacheControl)
9598
.build()
9699

97100
when:
@@ -114,6 +117,7 @@ class DataFetchingEnvironmentImplTest extends Specification {
114117
dfe.getOperationDefinition() == dfeCopy.getOperationDefinition()
115118
dfe.getVariables() == dfeCopy.getVariables()
116119
dfe.getDataLoader("dataLoader") == dataLoader
120+
dfe.getCacheControl() == cacheControl
117121
}
118122

119123
}

0 commit comments

Comments
 (0)