Skip to content

Commit b09ea56

Browse files
authored
Add hint to use reachable typenames for underlying type ownership (#716)
1 parent a25f455 commit b09ea56

4 files changed

Lines changed: 64 additions & 19 deletions

File tree

lib/src/main/java/graphql/nadel/NadelExecutionHints.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ package graphql.nadel
33
import graphql.nadel.hints.AllDocumentVariablesHint
44
import graphql.nadel.hints.LegacyOperationNamesHint
55
import graphql.nadel.hints.NadelDeferSupportHint
6+
import graphql.nadel.hints.NadelDisableSharedTypesHint
67
import graphql.nadel.hints.NadelExecuteOnEngineSchemaHint
78
import graphql.nadel.hints.NadelHydrationExecutableSourceFields
89
import graphql.nadel.hints.NadelHydrationFilterObjectTypesHint
10+
import graphql.nadel.hints.NadelReachableUnderlyingServiceTypesHint
911
import graphql.nadel.hints.NadelShadowUnderlyingTypeNameInvestigation
1012
import graphql.nadel.hints.NadelSharedTypeRenamesHint
1113
import graphql.nadel.hints.NadelShortCircuitEmptyQueryHint
@@ -24,6 +26,8 @@ data class NadelExecutionHints(
2426
val hydrationFilterObjectTypes: NadelHydrationFilterObjectTypesHint,
2527
val hydrationExecutableSourceFields: NadelHydrationExecutableSourceFields,
2628
val shadowUnderlyingTypeNameInvestigation: NadelShadowUnderlyingTypeNameInvestigation,
29+
val disableSharedTypes: NadelDisableSharedTypesHint,
30+
val useReachableUnderlyingServiceTypes: NadelReachableUnderlyingServiceTypesHint,
2731
) {
2832
/**
2933
* Returns a builder with the same field values as this object.
@@ -47,6 +51,8 @@ data class NadelExecutionHints(
4751
private var hydrationFilterObjectTypes = NadelHydrationFilterObjectTypesHint { false }
4852
private var hydrationExecutableSourceFields = NadelHydrationExecutableSourceFields { false }
4953
private var shadowUnderlyingTypeNameInvestigation = NadelShadowUnderlyingTypeNameInvestigation { false }
54+
private var disableSharedTypes = NadelDisableSharedTypesHint { false }
55+
private var useReachableUnderlyingServiceTypes = NadelReachableUnderlyingServiceTypesHint { false }
5056

5157
constructor()
5258

@@ -62,6 +68,8 @@ data class NadelExecutionHints(
6268
hydrationFilterObjectTypes = nadelExecutionHints.hydrationFilterObjectTypes
6369
hydrationExecutableSourceFields = nadelExecutionHints.hydrationExecutableSourceFields
6470
shadowUnderlyingTypeNameInvestigation = nadelExecutionHints.shadowUnderlyingTypeNameInvestigation
71+
disableSharedTypes = nadelExecutionHints.disableSharedTypes
72+
useReachableUnderlyingServiceTypes = nadelExecutionHints.useReachableUnderlyingServiceTypes
6573
}
6674

6775
fun legacyOperationNames(flag: LegacyOperationNamesHint): Builder {
@@ -119,6 +127,16 @@ data class NadelExecutionHints(
119127
return this
120128
}
121129

130+
fun disableSharedTypes(flag: NadelDisableSharedTypesHint): Builder {
131+
disableSharedTypes = flag
132+
return this
133+
}
134+
135+
fun useReachableUnderlyingServiceTypes(flag: NadelReachableUnderlyingServiceTypesHint): Builder {
136+
useReachableUnderlyingServiceTypes = flag
137+
return this
138+
}
139+
122140
fun build(): NadelExecutionHints {
123141
return NadelExecutionHints(
124142
legacyOperationNames,
@@ -132,6 +150,8 @@ data class NadelExecutionHints(
132150
hydrationFilterObjectTypes,
133151
hydrationExecutableSourceFields,
134152
shadowUnderlyingTypeNameInvestigation,
153+
disableSharedTypes,
154+
useReachableUnderlyingServiceTypes,
135155
)
136156
}
137157
}

lib/src/main/java/graphql/nadel/engine/transform/NadelServiceTypeFilterTransform.kt

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import graphql.introspection.Introspection
44
import graphql.nadel.Service
55
import graphql.nadel.ServiceExecutionHydrationDetails
66
import graphql.nadel.ServiceExecutionResult
7+
import graphql.nadel.definition.hydration.NadelHydrationConditionDefinition.Keyword.result
78
import graphql.nadel.engine.NadelExecutionContext
89
import graphql.nadel.engine.NadelServiceExecutionContext
910
import graphql.nadel.engine.blueprint.IntrospectionService
@@ -97,33 +98,43 @@ class NadelServiceTypeFilterTransform : NadelTransform<State> {
9798
val underlyingTypeNamesOwnedByService = executionBlueprint.getUnderlyingTypeNamesForService(service)
9899

99100
val shadow = executionContext.hints.shadowUnderlyingTypeNameInvestigation(executionContext)
101+
val useReachableUnderlyingServiceTypes = executionContext.hints.useReachableUnderlyingServiceTypes(service)
102+
val disableSharedTypes = executionContext.hints.disableSharedTypes(service)
100103

101104
fun checkSharedTypes(objectTypeName: String): Boolean {
102-
val result = executionContext.hints.sharedTypeRenames(service)
103-
&& executionBlueprint.getUnderlyingTypeName(objectTypeName) in underlyingTypeNamesOwnedByService
104-
if (result && shadow) {
105-
executionContext.hooks.reportSharedTypeDecisionImpact(executionContext, service, objectTypeName)
105+
return if (disableSharedTypes) {
106+
false
107+
} else {
108+
val result = executionContext.hints.sharedTypeRenames(service)
109+
&& executionBlueprint.getUnderlyingTypeName(objectTypeName) in underlyingTypeNamesOwnedByService
110+
if (result && shadow) {
111+
executionContext.hooks.reportSharedTypeDecisionImpact(executionContext, service, objectTypeName)
112+
}
113+
result
106114
}
107-
return result
108115
}
109116

110117
fun checkUnderlyingType(objectTypeName: String): Boolean {
111-
val result = objectTypeName in underlyingTypeNamesOwnedByService
112-
if (shadow) {
113-
val reachableUnderlyingTypeNameCheck =
114-
objectTypeName in executionBlueprint.getReachableUnderlyingTypeNamesForService(service)
115-
val reducedUnderlyingTypeNameCheck =
116-
objectTypeName in executionBlueprint.getReducedUnderlyingTypeNamesForService(service)
117-
if (result != reachableUnderlyingTypeNameCheck) {
118-
executionContext.hooks
119-
.reportReachableTypeDecisionInconsistency(executionContext, service, objectTypeName)
120-
}
121-
if (result != reducedUnderlyingTypeNameCheck) {
122-
executionContext.hooks
123-
.reportReducedTypeDecisionInconsistency(executionContext, service, objectTypeName)
118+
return if (useReachableUnderlyingServiceTypes) {
119+
objectTypeName in executionBlueprint.getReachableUnderlyingTypeNamesForService(service)
120+
} else {
121+
val result = objectTypeName in underlyingTypeNamesOwnedByService
122+
if (shadow) {
123+
val reachableUnderlyingTypeNameCheck =
124+
objectTypeName in executionBlueprint.getReachableUnderlyingTypeNamesForService(service)
125+
val reducedUnderlyingTypeNameCheck =
126+
objectTypeName in executionBlueprint.getReducedUnderlyingTypeNamesForService(service)
127+
if (result != reachableUnderlyingTypeNameCheck) {
128+
executionContext.hooks
129+
.reportReachableTypeDecisionInconsistency(executionContext, service, objectTypeName)
130+
}
131+
if (result != reducedUnderlyingTypeNameCheck) {
132+
executionContext.hooks
133+
.reportReducedTypeDecisionInconsistency(executionContext, service, objectTypeName)
134+
}
124135
}
136+
result
125137
}
126-
return result
127138
}
128139

129140
// Assume for most cases there aren't foreign types so there is no point filtering to a new List
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package graphql.nadel.hints
2+
3+
import graphql.nadel.Service
4+
5+
fun interface NadelDisableSharedTypesHint {
6+
operator fun invoke(service: Service): Boolean
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package graphql.nadel.hints
2+
3+
import graphql.nadel.Service
4+
5+
fun interface NadelReachableUnderlyingServiceTypesHint {
6+
operator fun invoke(service: Service): Boolean
7+
}

0 commit comments

Comments
 (0)