Skip to content

Commit 2eadcac

Browse files
authored
Merge pull request #80 from intuit/fix-fieldresolver-graphqlctx
Fix fieldresolver graphqlctx
2 parents 8a007ab + 2577b70 commit 2eadcac

File tree

4 files changed

+50
-23
lines changed

4 files changed

+50
-23
lines changed

src/main/java/com/intuit/graphql/orchestrator/batch/FieldResolverBatchLoader.java

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.intuit.graphql.orchestrator.batch;
22

33
import static com.intuit.graphql.orchestrator.GraphQLOrchestrator.DATA_LOADER_REGISTRY_CONTEXT_KEY;
4+
import static com.intuit.graphql.orchestrator.resolverdirective.FieldResolverDirectiveUtil.FQN_FIELD_SEPARATOR;
5+
import static com.intuit.graphql.orchestrator.resolverdirective.FieldResolverDirectiveUtil.FQN_KEYWORD_QUERY;
46
import static com.intuit.graphql.orchestrator.resolverdirective.FieldResolverDirectiveUtil.createFieldResolverOperationName;
57
import static graphql.language.AstPrinter.printAstCompact;
68
import static graphql.schema.GraphQLTypeUtil.unwrapAll;
@@ -70,7 +72,7 @@ public FieldResolverBatchLoader(FieldResolverContext fieldResolverContext) {
7072
this.fieldResolverContext = fieldResolverContext;
7173
ResolverDirectiveDefinition resolverDirectiveDefinition = fieldResolverContext.getResolverDirectiveDefinition();
7274

73-
this.resolverSelectedFields = StringUtils.split(resolverDirectiveDefinition.getField(), '.');
75+
this.resolverSelectedFields = StringUtils.split(resolverDirectiveDefinition.getField(), FQN_FIELD_SEPARATOR);
7476
this.batchResultTransformer = new FieldResolverBatchResultTransformer(resolverSelectedFields, fieldResolverContext);
7577
}
7678

@@ -118,25 +120,39 @@ private OperationDefinition removeExternalFields(OperationDefinition operationDe
118120
}
119121

120122
private ServiceMetadata getServiceMetadata(DataFetchingEnvironment dataFetchingEnvironment) {
121-
GraphQLCodeRegistry graphQLCodeRegistry = dataFetchingEnvironment.getGraphQLSchema().getCodeRegistry();
122-
GraphQLFieldDefinition graphQLFieldDefinition = dataFetchingEnvironment.getFieldDefinition();
123+
GraphQLSchema graphQLSchema = dataFetchingEnvironment.getGraphQLSchema();
124+
GraphQLCodeRegistry graphQLCodeRegistry = graphQLSchema.getCodeRegistry();
123125

124-
FieldContext fieldContext = this.fieldResolverContext.getTargetFieldContext();
125-
FieldCoordinates fieldCoordinates = fieldContext.getFieldCoordinates();
126+
int start = 0;
127+
if (FQN_KEYWORD_QUERY.equals(resolverSelectedFields[0])) {
128+
start = 1;
129+
}
126130

127-
DataFetcher<?> dataFetcher = graphQLCodeRegistry.getDataFetcher(fieldCoordinates, graphQLFieldDefinition);
128-
if (Objects.nonNull(dataFetcher) && dataFetcher instanceof ServiceDataFetcher) {
129-
ServiceDataFetcher serviceDataFetcher = (ServiceDataFetcher) dataFetcher;
130-
return serviceDataFetcher.getServiceMetadata();
131-
} else {
132-
throw FieldResolverGraphQLError.builder()
133-
.errorMessage("ServiceDataFetcher not found.")
134-
.fieldName(fieldCoordinates.getFieldName())
135-
.parentTypeName(fieldCoordinates.getTypeName())
136-
.resolverDirectiveDefinition(this.fieldResolverContext.getResolverDirectiveDefinition())
137-
.serviceNameSpace(fieldResolverContext.getServiceNamespace())
138-
.build();
131+
GraphQLFieldsContainer currentParentType = graphQLSchema.getQueryType();
132+
for (int i = start; i < resolverSelectedFields.length; i++) {
133+
String fieldName = resolverSelectedFields[i];
134+
GraphQLFieldDefinition graphQLFieldDefinition = currentParentType.getFieldDefinition(fieldName);
135+
FieldCoordinates fieldCoordinates = FieldCoordinates.coordinates(currentParentType.getName(), fieldName);
136+
DataFetcher<?> dataFetcher = graphQLCodeRegistry.getDataFetcher(fieldCoordinates, graphQLFieldDefinition);
137+
if (Objects.nonNull(dataFetcher) && dataFetcher instanceof ServiceDataFetcher) {
138+
ServiceDataFetcher serviceDataFetcher = (ServiceDataFetcher) dataFetcher;
139+
return serviceDataFetcher.getServiceMetadata();
140+
}
141+
if (!(graphQLFieldDefinition.getType() instanceof GraphQLFieldsContainer)) {
142+
break;
143+
}
144+
currentParentType = (GraphQLFieldsContainer) graphQLFieldDefinition.getType();
139145
}
146+
147+
FieldContext fieldContext = this.fieldResolverContext.getTargetFieldContext();
148+
FieldCoordinates fieldCoordinates = fieldContext.getFieldCoordinates();
149+
throw FieldResolverGraphQLError.builder()
150+
.errorMessage("Service DataFetcher not found.")
151+
.fieldName(fieldCoordinates.getFieldName())
152+
.parentTypeName(fieldCoordinates.getTypeName())
153+
.resolverDirectiveDefinition(this.fieldResolverContext.getResolverDirectiveDefinition())
154+
.serviceNameSpace(fieldResolverContext.getServiceNamespace())
155+
.build();
140156
}
141157

142158
private List<Definition<FragmentDefinition>> createResolverQueryFragmentDefinitions(DataFetchingEnvironment dataFetchingEnvironment) {

src/main/java/com/intuit/graphql/orchestrator/resolverdirective/FieldResolverDirectiveUtil.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ public class FieldResolverDirectiveUtil {
2828
public static final String RESOLVER_DIRECTIVE_NAME = "resolver";
2929
public static final String FIELD_REFERENCE_PREFIX = "$";
3030

31+
public static final String FQN_KEYWORD_QUERY = "query";
32+
public static final char FQN_FIELD_SEPARATOR = '.';
33+
3134
public static final CharSequence OPERATION_NAME_SEPARATOR = "_";
3235
public static final CharSequence RESOLVER_DIRECTIVE_QUERY_NAME = "Resolver_Directive_Query";
3336

src/main/java/com/intuit/graphql/orchestrator/schema/transform/FieldResolverTransformerPostMerge.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.intuit.graphql.orchestrator.schema.transform;
22

3+
import static com.intuit.graphql.orchestrator.resolverdirective.FieldResolverDirectiveUtil.FQN_FIELD_SEPARATOR;
4+
import static com.intuit.graphql.orchestrator.resolverdirective.FieldResolverDirectiveUtil.FQN_KEYWORD_QUERY;
35
import static com.intuit.graphql.orchestrator.utils.XtextGraphUtils.addToCodeRegistry;
46
import static com.intuit.graphql.orchestrator.utils.XtextTypeUtils.createNamedType;
57
import static com.intuit.graphql.orchestrator.utils.XtextTypeUtils.getFieldDefinitions;
@@ -198,9 +200,9 @@ private void replacePlaceholderTypeWithActual(FieldResolverContext fieldResolver
198200

199201
private FieldDefinition getFieldDefinitionByFQN(final String queryFieldFQN, XtextGraph xtextGraph) {
200202

201-
String queryFieldFQNNoQuery = StringUtils.removeStart(queryFieldFQN ,"query."); // remove if exists
203+
String queryFieldFQNNoQuery = StringUtils.removeStart(queryFieldFQN ,FQN_KEYWORD_QUERY + FQN_FIELD_SEPARATOR); // remove if exists
202204

203-
String[] queryFieldFQNTokens = StringUtils.split(queryFieldFQNNoQuery, '.');
205+
String[] queryFieldFQNTokens = StringUtils.split(queryFieldFQNNoQuery, FQN_FIELD_SEPARATOR);
204206
if (ArrayUtils.isEmpty(queryFieldFQNTokens)) {
205207
String errorMessage = String.format("Failed to tokenize queryFieldFQN. queryFieldFQN=%s", queryFieldFQN);
206208
throw new IllegalArgumentException(errorMessage);

src/test/groovy/com/intuit/graphql/orchestrator/integration/NestedFieldResolverSpec.groovy

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ class NestedFieldResolverSpec extends BaseIntegrationTestSpecification {
1111

1212
def schemaA = """
1313
type Query {
14+
arootField: ARootType
15+
}
16+
17+
type ARootType {
1418
aTopField(p1: String!): AObjectType!
1519
}
1620
@@ -28,11 +32,13 @@ class NestedFieldResolverSpec extends BaseIntegrationTestSpecification {
2832
}
2933
"""
3034

31-
def QUERY_A = "query Resolver_Directive_Query {aTopField_0:aTopField(p1:\"bObjectFieldValue1\") {aObjectField} aTopField_1:aTopField(p1:\"bObjectFieldValue2\") {aObjectField cTopField {cObjectField}}}"
35+
def QUERY_A = "query Resolver_Directive_Query {arootField {aTopField_0:aTopField(p1:\"bObjectFieldValue1\") {aObjectField}} arootField {aTopField_1:aTopField(p1:\"bObjectFieldValue2\") {aObjectField cTopField {cObjectField}}}}"
3236
def mockServiceResponseA = [
3337
(QUERY_A): [data: [
34-
aTopField_0: [ aObjectField: "aObjectFieldValue1"],
35-
aTopField_1: [ aObjectField: "aObjectFieldValue2"]
38+
arootField : [
39+
aTopField_0: [ aObjectField: "aObjectFieldValue1"],
40+
aTopField_1: [ aObjectField: "aObjectFieldValue2"]
41+
]
3642
]]
3743
]
3844

@@ -43,7 +49,7 @@ class NestedFieldResolverSpec extends BaseIntegrationTestSpecification {
4349
4450
type BObjectType {
4551
bObjectField: String
46-
aTopField: AObjectType @resolver(field: "aTopField", arguments: [{name : "p1", value: "\$bObjectField"}])
52+
aTopField: AObjectType @resolver(field: "arootField.aTopField", arguments: [{name : "p1", value: "\$bObjectField"}])
4753
}
4854
4955
type AObjectType

0 commit comments

Comments
 (0)