Skip to content

Commit 49ce96f

Browse files
committed
graphql-java#278 - merged in upstream master
2 parents 9d94784 + 8f1681d commit 49ce96f

9 files changed

Lines changed: 113 additions & 31 deletions

File tree

src/main/antlr/Graphql.g4

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ typeCondition : 'on' typeName;
5959

6060
// Value
6161

62-
name: NAME | QUERY | MUTATION | SCHEMA | SCALAR | TYPE | INTERFACE | IMPLEMENTS | ENUM | UNION | INPUT | EXTEND | DIRECTIVE;
62+
name: NAME | FRAGMENT | QUERY | MUTATION | SCHEMA | SCALAR | TYPE | INTERFACE | IMPLEMENTS | ENUM | UNION | INPUT | EXTEND | DIRECTIVE;
6363

6464
value :
6565
IntValue |
@@ -176,6 +176,7 @@ directiveLocations '|' directiveLocation
176176

177177
BooleanValue: 'true' | 'false';
178178

179+
FRAGMENT: 'fragment';
179180
QUERY: 'query';
180181
MUTATION: 'mutation';
181182
SCHEMA: 'schema';

src/main/java/graphql/GraphQL.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ public class GraphQL {
2727

2828

2929
private final GraphQLSchema graphQLSchema;
30-
private final ExecutionStrategy executionStrategy;
30+
private final ExecutionStrategy queryStrategy;
31+
private final ExecutionStrategy mutationStrategy;
3132
//
3233
// later PR changes will allow api consumers to provide their own id provider
3334
//
@@ -44,13 +45,18 @@ public ExecutionId generate(String query, String operationName, Object context)
4445
private static final Logger log = LoggerFactory.getLogger(GraphQL.class);
4546

4647
public GraphQL(GraphQLSchema graphQLSchema) {
47-
this(graphQLSchema, null);
48+
this(graphQLSchema, null, null);
4849
}
4950

5051

51-
public GraphQL(GraphQLSchema graphQLSchema, ExecutionStrategy executionStrategy) {
52+
public GraphQL(GraphQLSchema graphQLSchema, ExecutionStrategy queryStrategy) {
53+
this(graphQLSchema, queryStrategy, null);
54+
}
55+
56+
public GraphQL(GraphQLSchema graphQLSchema, ExecutionStrategy queryStrategy, ExecutionStrategy mutationStrategy) {
5257
this.graphQLSchema = graphQLSchema;
53-
this.executionStrategy = executionStrategy;
58+
this.queryStrategy = queryStrategy;
59+
this.mutationStrategy = mutationStrategy;
5460
}
5561

5662
public ExecutionResult execute(String requestString) {
@@ -88,10 +94,9 @@ public ExecutionResult execute(String requestString, String operationName, Objec
8894
if (validationErrors.size() > 0) {
8995
return new ExecutionResultImpl(validationErrors);
9096
}
91-
9297
ExecutionId executionId = idProvider.generate(requestString, operationName, context);
9398

94-
Execution execution = new Execution(executionStrategy);
99+
Execution execution = new Execution(queryStrategy, mutationStrategy);
95100
return execution.execute(executionId, graphQLSchema, context, document, operationName, arguments);
96101
}
97102

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,20 @@
1616

1717
public class Execution {
1818

19-
private final FieldCollector fieldCollector = new FieldCollector();
20-
private final ExecutionStrategy strategy;
19+
private FieldCollector fieldCollector = new FieldCollector();
20+
private ExecutionStrategy queryStrategy;
21+
private ExecutionStrategy mutationStrategy;
2122

22-
public Execution(ExecutionStrategy executionStrategy) {
23-
this.strategy = executionStrategy == null ? new SimpleExecutionStrategy() : executionStrategy;
23+
public Execution(ExecutionStrategy queryStrategy, ExecutionStrategy mutationStrategy) {
24+
this.queryStrategy = queryStrategy != null ? queryStrategy : new SimpleExecutionStrategy();
25+
this.mutationStrategy = mutationStrategy != null ? mutationStrategy : new SimpleExecutionStrategy();
2426
}
2527

2628
public ExecutionResult execute(ExecutionId executionId, GraphQLSchema graphQLSchema, Object root, Document document, String operationName, Map<String, Object> args) {
2729
ExecutionContextBuilder executionContextBuilder = new ExecutionContextBuilder(new ValuesResolver());
2830
ExecutionContext executionContext = executionContextBuilder
2931
.executionId(executionId)
30-
.build(graphQLSchema, strategy, root, document, operationName, args);
31-
32+
.build(graphQLSchema, queryStrategy, mutationStrategy, root, document, operationName, args);
3233
return executeOperation(executionContext, root, executionContext.getOperationDefinition());
3334
}
3435

@@ -54,9 +55,9 @@ private ExecutionResult executeOperation(
5455
fieldCollector.collectFields(executionContext, operationRootType, operationDefinition.getSelectionSet(), new ArrayList<String>(), fields);
5556

5657
if (operationDefinition.getOperation() == OperationDefinition.Operation.MUTATION) {
57-
return new SimpleExecutionStrategy().execute(executionContext, operationRootType, root, fields);
58+
return mutationStrategy.execute(executionContext, operationRootType, root, fields);
5859
} else {
59-
return strategy.execute(executionContext, operationRootType, root, fields);
60+
return queryStrategy.execute(executionContext, operationRootType, root, fields);
6061
}
6162
}
6263
}

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,19 @@ public class ExecutionContext {
1414

1515
private final GraphQLSchema graphQLSchema;
1616
private final ExecutionId executionId;
17-
private final ExecutionStrategy executionStrategy;
17+
private final ExecutionStrategy queryStrategy;
18+
private final ExecutionStrategy mutationStrategy;
1819
private final Map<String, FragmentDefinition> fragmentsByName;
1920
private final OperationDefinition operationDefinition;
2021
private final Map<String, Object> variables;
2122
private final Object root;
2223
private final List<GraphQLError> errors = new CopyOnWriteArrayList<GraphQLError>();
2324

24-
public ExecutionContext(GraphQLSchema graphQLSchema, ExecutionId executionId, ExecutionStrategy executionStrategy, Map<String, FragmentDefinition> fragmentsByName, OperationDefinition operationDefinition, Map<String, Object> variables, Object root) {
25+
public ExecutionContext(GraphQLSchema graphQLSchema, ExecutionId executionId, ExecutionStrategy queryStrategy, ExecutionStrategy mutationStrategy, Map<String, FragmentDefinition> fragmentsByName, OperationDefinition operationDefinition, Map<String, Object> variables, Object root) {
2526
this.graphQLSchema = graphQLSchema;
2627
this.executionId = executionId;
27-
this.executionStrategy = executionStrategy;
28+
this.queryStrategy = queryStrategy;
29+
this.mutationStrategy = mutationStrategy;
2830
this.fragmentsByName = fragmentsByName;
2931
this.operationDefinition = operationDefinition;
3032
this.variables = variables;
@@ -67,8 +69,11 @@ public List<GraphQLError> getErrors() {
6769
return errors;
6870
}
6971

70-
public ExecutionStrategy getExecutionStrategy() {
71-
return executionStrategy;
72+
public ExecutionStrategy getQueryStrategy() {
73+
return queryStrategy;
7274
}
7375

76+
public ExecutionStrategy getMutationStrategy() {
77+
return mutationStrategy;
78+
}
7479
}

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,9 @@ public ExecutionContextBuilder executionId(ExecutionId executionId) {
2828
return this;
2929
}
3030

31-
public ExecutionContext build(GraphQLSchema graphQLSchema, ExecutionStrategy executionStrategy, Object root, Document document, String operationName, Map<String, Object> args) {
31+
public ExecutionContext build(GraphQLSchema graphQLSchema, ExecutionStrategy queryStrategy, ExecutionStrategy mutationStrategy, Object root, Document document, String operationName, Map<String, Object> args) {
3232
// preconditions
3333
assertNotNull(executionId,"You must provide a query identifier");
34-
3534
Map<String, FragmentDefinition> fragmentsByName = new LinkedHashMap<String, FragmentDefinition>();
3635
Map<String, OperationDefinition> operationsByName = new LinkedHashMap<String, OperationDefinition>();
3736

@@ -58,13 +57,13 @@ public ExecutionContext build(GraphQLSchema graphQLSchema, ExecutionStrategy exe
5857
if (operation == null) {
5958
throw new GraphQLException();
6059
}
61-
6260
Map<String, Object> variableValues = valuesResolver.getVariableValues(graphQLSchema, operation.getVariableDefinitions(), args);
6361

6462
return new ExecutionContext(
6563
graphQLSchema,
6664
executionId,
67-
executionStrategy,
65+
queryStrategy,
66+
mutationStrategy,
6867
fragmentsByName,
6968
operation,
7069
variableValues,

src/main/java/graphql/execution/ExecutionStrategy.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,9 @@ protected ExecutionResult completeValue(ExecutionContext executionContext, Graph
8282
fieldCollector.collectFields(executionContext, resolvedType, field.getSelectionSet(), visitedFragments, subFields);
8383
}
8484

85-
// Calling this from the executionContext so that you can shift from the simple execution strategy for mutations
86-
// back to the desired strategy.
85+
// Calling this from the executionContext to ensure we shift back from mutation strategy to the query strategy.
8786

88-
return executionContext.getExecutionStrategy().execute(executionContext, resolvedType, result, subFields);
87+
return executionContext.getQueryStrategy().execute(executionContext, resolvedType, result, subFields);
8988
}
9089

9190
private ExecutionResult completeValueForList(ExecutionContext executionContext, GraphQLList fieldType, List<Field> fields, Object result) {

src/test/groovy/graphql/execution/ExecutionStrategySpec.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class ExecutionStrategySpec extends Specification {
2121
}
2222

2323
def buildContext() {
24-
new ExecutionContext(null, null, executionStrategy, null, null, null, null)
24+
new ExecutionContext(null,null, executionStrategy,executionStrategy,null,null,null,null)
2525
}
2626

2727
def "completes value for a java.util.List"() {
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package graphql.execution
2+
3+
import graphql.MutationSchema
4+
import graphql.parser.Parser
5+
import spock.lang.Specification
6+
7+
class ExecutionTest extends Specification {
8+
9+
def parser = new Parser()
10+
def mutationStrategy = Mock(ExecutionStrategy)
11+
def queryStrategy = Mock(ExecutionStrategy)
12+
def execution = new Execution(queryStrategy, mutationStrategy)
13+
14+
def "query strategy is used for query requests"() {
15+
given:
16+
def mutationStrategy = Mock(ExecutionStrategy)
17+
18+
def queryStrategy = Mock(ExecutionStrategy)
19+
def execution = new Execution(queryStrategy, mutationStrategy)
20+
21+
def query = '''
22+
query {
23+
numberHolder {
24+
theNumber
25+
}
26+
}
27+
'''
28+
def document = parser.parseDocument(query)
29+
30+
when:
31+
execution.execute(MutationSchema.schema, null, document, null, null)
32+
33+
then:
34+
1 * queryStrategy.execute(*_)
35+
0 * mutationStrategy.execute(*_)
36+
}
37+
38+
def "mutation strategy is used for mutation requests"() {
39+
given:
40+
def query = '''
41+
mutation {
42+
changeTheNumber(newNumber: 1) {
43+
theNumber
44+
}
45+
}
46+
'''
47+
def document = parser.parseDocument(query)
48+
49+
when:
50+
execution.execute(MutationSchema.schema, null, document, null, null)
51+
52+
then:
53+
0 * queryStrategy.execute(*_)
54+
1 * mutationStrategy.execute(*_)
55+
}
56+
}

src/test/groovy/graphql/parser/ParserTest.groovy

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -378,9 +378,9 @@ class ParserTest extends Specification {
378378

379379
}
380380

381-
def "`'query'` can be used as field name"() {
381+
def "keywords can be used as field names"() {
382382
given:
383-
def input = "{ query }"
383+
def input = "{ ${name} }"
384384

385385
when:
386386
Document document = new Parser().parseDocument(input)
@@ -389,7 +389,23 @@ class ParserTest extends Specification {
389389
document.definitions.size() == 1
390390
document.definitions[0] instanceof OperationDefinition
391391
document.definitions[0].operation == OperationDefinition.Operation.QUERY
392-
assertField(document.definitions[0] as OperationDefinition, "query")
392+
assertField(document.definitions[0] as OperationDefinition, name)
393+
394+
where:
395+
name | _
396+
'fragment' | _
397+
'query' | _
398+
'mutation' | _
399+
'schema' | _
400+
'scalar' | _
401+
'type' | _
402+
'interface' | _
403+
'implements' | _
404+
'enum' | _
405+
'union' | _
406+
'input' | _
407+
'extend' | _
408+
'directive' | _
393409
}
394410

395411
def "StarWars schema"() {

0 commit comments

Comments
 (0)