From 5ffcff72920cbf7833abbeec90fd484657ac1fda Mon Sep 17 00:00:00 2001 From: Steven Barker Date: Mon, 18 Dec 2023 14:45:29 +1300 Subject: [PATCH 1/3] Add code to parse when condition in blueprint --- .../NadelExecutionBlueprintFactory.kt | 33 +++++++++++++++++-- .../engine/blueprint/NadelFieldInstruction.kt | 8 +++++ .../hydration/NadelHydrationWhenCondition.kt | 32 ++++++++++++++++++ 3 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 lib/src/main/java/graphql/nadel/engine/blueprint/hydration/NadelHydrationWhenCondition.kt diff --git a/lib/src/main/java/graphql/nadel/engine/blueprint/NadelExecutionBlueprintFactory.kt b/lib/src/main/java/graphql/nadel/engine/blueprint/NadelExecutionBlueprintFactory.kt index 34b6b586e..3609f276d 100644 --- a/lib/src/main/java/graphql/nadel/engine/blueprint/NadelExecutionBlueprintFactory.kt +++ b/lib/src/main/java/graphql/nadel/engine/blueprint/NadelExecutionBlueprintFactory.kt @@ -8,7 +8,6 @@ import graphql.Scalars.GraphQLString import graphql.language.EnumTypeDefinition import graphql.language.FieldDefinition import graphql.language.ImplementingTypeDefinition -import graphql.language.StringValue import graphql.nadel.Service import graphql.nadel.dsl.FieldMappingDefinition import graphql.nadel.dsl.RemoteArgumentSource.SourceType.FieldArgument @@ -20,6 +19,7 @@ import graphql.nadel.engine.blueprint.hydration.NadelBatchHydrationMatchStrategy import graphql.nadel.engine.blueprint.hydration.NadelHydrationActorInputDef import graphql.nadel.engine.blueprint.hydration.NadelHydrationActorInputDef.ValueSource.FieldResultValue import graphql.nadel.engine.blueprint.hydration.NadelHydrationStrategy +import graphql.nadel.engine.blueprint.hydration.NadelHydrationWhenCondition import graphql.nadel.engine.transform.query.NadelQueryPath import graphql.nadel.engine.util.AnyImplementingTypeDefinition import graphql.nadel.engine.util.AnyNamedNode @@ -265,9 +265,37 @@ private class Factory( is NadelHydrationActorInputDef.ValueSource.StaticValue -> null } }, + condition = getHydrationCondition(hydration), ) } + private fun getHydrationCondition(): NadelHydrationWhenCondition? { + return null + } + + private fun getHydrationCondition(hydration: UnderlyingServiceHydration): NadelHydrationWhenCondition? { + if (hydration.conditionalHydration == null) { + return null + } + if (hydration.conditionalHydration.predicate.equals != null) { + return NadelHydrationWhenCondition.ResultEquals( + fieldPath = NadelQueryPath(hydration.conditionalHydration.sourceField), + value = hydration.conditionalHydration.predicate.equals) + } + if (hydration.conditionalHydration.predicate.startsWith != null){ + return NadelHydrationWhenCondition.StringResultStartsWith( + fieldPath = NadelQueryPath(hydration.conditionalHydration.sourceField), + value = hydration.conditionalHydration.predicate.startsWith) + } + if (hydration.conditionalHydration.predicate.matches != null){ + return NadelHydrationWhenCondition.StringResultMatches( + fieldPath = NadelQueryPath(hydration.conditionalHydration.sourceField), + regex = hydration.conditionalHydration.predicate.matches + ) + } + error("a conditional hydration is defined but doesnt have any predicate") + } + private fun getHydrationStrategy( hydratedFieldParentType: GraphQLObjectType, hydratedFieldDef: GraphQLFieldDefinition, @@ -352,6 +380,7 @@ private class Factory( batchHydrationMatchStrategy = matchStrategy, actorFieldDef = actorFieldDef, actorFieldContainer = actorFieldContainer, + condition = getHydrationCondition(hydration), sourceFields = Unit.let { val paths = (when (matchStrategy) { NadelBatchHydrationMatchStrategy.MatchIndex -> emptyList() @@ -489,7 +518,7 @@ private class Factory( } StaticArgument -> { NadelHydrationActorInputDef.ValueSource.StaticValue( - value = remoteArgDef.remoteArgumentSource.staticValue!! + value = remoteArgDef.remoteArgumentSource.staticValue!! ) } } diff --git a/lib/src/main/java/graphql/nadel/engine/blueprint/NadelFieldInstruction.kt b/lib/src/main/java/graphql/nadel/engine/blueprint/NadelFieldInstruction.kt index d5d73c96d..f3702e4a1 100644 --- a/lib/src/main/java/graphql/nadel/engine/blueprint/NadelFieldInstruction.kt +++ b/lib/src/main/java/graphql/nadel/engine/blueprint/NadelFieldInstruction.kt @@ -4,6 +4,7 @@ import graphql.nadel.Service import graphql.nadel.engine.blueprint.hydration.NadelBatchHydrationMatchStrategy import graphql.nadel.engine.blueprint.hydration.NadelHydrationActorInputDef import graphql.nadel.engine.blueprint.hydration.NadelHydrationStrategy +import graphql.nadel.engine.blueprint.hydration.NadelHydrationWhenCondition import graphql.nadel.engine.transform.query.NadelQueryPath import graphql.schema.FieldCoordinates import graphql.schema.GraphQLFieldDefinition @@ -82,6 +83,11 @@ interface NadelGenericHydrationInstruction { * The container of the actor field in the overall schema referenced by [queryPathToActorField]. */ val actorFieldContainer: GraphQLFieldsContainer + + /** + * The optional definition for conditional hydrations + */ + val condition: NadelHydrationWhenCondition? } data class NadelHydrationFieldInstruction( @@ -95,6 +101,7 @@ data class NadelHydrationFieldInstruction( override val sourceFields: List, override val actorFieldDef: GraphQLFieldDefinition, override val actorFieldContainer: GraphQLFieldsContainer, + override val condition: NadelHydrationWhenCondition?, val hydrationStrategy: NadelHydrationStrategy, ) : NadelFieldInstruction(), NadelGenericHydrationInstruction @@ -109,6 +116,7 @@ data class NadelBatchHydrationFieldInstruction( override val sourceFields: List, override val actorFieldDef: GraphQLFieldDefinition, override val actorFieldContainer: GraphQLFieldsContainer, + override val condition: NadelHydrationWhenCondition?, val batchSize: Int, val batchHydrationMatchStrategy: NadelBatchHydrationMatchStrategy, ) : NadelFieldInstruction(), NadelGenericHydrationInstruction diff --git a/lib/src/main/java/graphql/nadel/engine/blueprint/hydration/NadelHydrationWhenCondition.kt b/lib/src/main/java/graphql/nadel/engine/blueprint/hydration/NadelHydrationWhenCondition.kt new file mode 100644 index 000000000..9b0f6c29d --- /dev/null +++ b/lib/src/main/java/graphql/nadel/engine/blueprint/hydration/NadelHydrationWhenCondition.kt @@ -0,0 +1,32 @@ +package graphql.nadel.engine.blueprint.hydration + +import graphql.nadel.engine.transform.query.NadelQueryPath +sealed class NadelHydrationWhenCondition { + abstract fun evaluate(resultId: String): Boolean + + data class ResultEquals( + val fieldPath: NadelQueryPath, + val value: Any, + ): NadelHydrationWhenCondition() { + override fun evaluate(resultId: String): Boolean { + TODO("Not yet implemented") + } + } + data class StringResultMatches( + val fieldPath: NadelQueryPath, + val regex: Regex, + ): NadelHydrationWhenCondition() { + override fun evaluate(resultId: String): Boolean { + TODO("Not yet implemented") + } + } + + data class StringResultStartsWith( + val fieldPath: NadelQueryPath, + val value: String, + ): NadelHydrationWhenCondition() { + override fun evaluate(resultId: String): Boolean { + TODO("Not yet implemented") + } + } +} \ No newline at end of file From d242d24f781a37b3f0f5d930f3cc4cefe9a0c884 Mon Sep 17 00:00:00 2001 From: Steven Barker Date: Mon, 18 Dec 2023 14:46:13 +1300 Subject: [PATCH 2/3] Add code to parse when condition in blueprint --- .../engine/blueprint/NadelExecutionBlueprintFactory.kt | 10 ++++++---- .../blueprint/hydration/NadelHydrationWhenCondition.kt | 8 +++++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/src/main/java/graphql/nadel/engine/blueprint/NadelExecutionBlueprintFactory.kt b/lib/src/main/java/graphql/nadel/engine/blueprint/NadelExecutionBlueprintFactory.kt index 3609f276d..e74cad105 100644 --- a/lib/src/main/java/graphql/nadel/engine/blueprint/NadelExecutionBlueprintFactory.kt +++ b/lib/src/main/java/graphql/nadel/engine/blueprint/NadelExecutionBlueprintFactory.kt @@ -280,14 +280,16 @@ private class Factory( if (hydration.conditionalHydration.predicate.equals != null) { return NadelHydrationWhenCondition.ResultEquals( fieldPath = NadelQueryPath(hydration.conditionalHydration.sourceField), - value = hydration.conditionalHydration.predicate.equals) + value = hydration.conditionalHydration.predicate.equals + ) } - if (hydration.conditionalHydration.predicate.startsWith != null){ + if (hydration.conditionalHydration.predicate.startsWith != null) { return NadelHydrationWhenCondition.StringResultStartsWith( fieldPath = NadelQueryPath(hydration.conditionalHydration.sourceField), - value = hydration.conditionalHydration.predicate.startsWith) + value = hydration.conditionalHydration.predicate.startsWith + ) } - if (hydration.conditionalHydration.predicate.matches != null){ + if (hydration.conditionalHydration.predicate.matches != null) { return NadelHydrationWhenCondition.StringResultMatches( fieldPath = NadelQueryPath(hydration.conditionalHydration.sourceField), regex = hydration.conditionalHydration.predicate.matches diff --git a/lib/src/main/java/graphql/nadel/engine/blueprint/hydration/NadelHydrationWhenCondition.kt b/lib/src/main/java/graphql/nadel/engine/blueprint/hydration/NadelHydrationWhenCondition.kt index 9b0f6c29d..19fc68c2b 100644 --- a/lib/src/main/java/graphql/nadel/engine/blueprint/hydration/NadelHydrationWhenCondition.kt +++ b/lib/src/main/java/graphql/nadel/engine/blueprint/hydration/NadelHydrationWhenCondition.kt @@ -1,21 +1,23 @@ package graphql.nadel.engine.blueprint.hydration import graphql.nadel.engine.transform.query.NadelQueryPath + sealed class NadelHydrationWhenCondition { abstract fun evaluate(resultId: String): Boolean data class ResultEquals( val fieldPath: NadelQueryPath, val value: Any, - ): NadelHydrationWhenCondition() { + ) : NadelHydrationWhenCondition() { override fun evaluate(resultId: String): Boolean { TODO("Not yet implemented") } } + data class StringResultMatches( val fieldPath: NadelQueryPath, val regex: Regex, - ): NadelHydrationWhenCondition() { + ) : NadelHydrationWhenCondition() { override fun evaluate(resultId: String): Boolean { TODO("Not yet implemented") } @@ -24,7 +26,7 @@ sealed class NadelHydrationWhenCondition { data class StringResultStartsWith( val fieldPath: NadelQueryPath, val value: String, - ): NadelHydrationWhenCondition() { + ) : NadelHydrationWhenCondition() { override fun evaluate(resultId: String): Boolean { TODO("Not yet implemented") } From 19328d162e10318f78dec08358be5b58793bf29e Mon Sep 17 00:00:00 2001 From: sbarker2 <109047597+sbarker2@users.noreply.github.com> Date: Mon, 18 Dec 2023 14:58:19 +1300 Subject: [PATCH 3/3] Apply suggestions from code review Co-authored-by: Franklin Wang <9077461+gnawf@users.noreply.github.com> --- .../engine/blueprint/NadelExecutionBlueprintFactory.kt | 6 +----- .../blueprint/hydration/NadelHydrationWhenCondition.kt | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/src/main/java/graphql/nadel/engine/blueprint/NadelExecutionBlueprintFactory.kt b/lib/src/main/java/graphql/nadel/engine/blueprint/NadelExecutionBlueprintFactory.kt index e74cad105..9c45cbdd3 100644 --- a/lib/src/main/java/graphql/nadel/engine/blueprint/NadelExecutionBlueprintFactory.kt +++ b/lib/src/main/java/graphql/nadel/engine/blueprint/NadelExecutionBlueprintFactory.kt @@ -269,10 +269,6 @@ private class Factory( ) } - private fun getHydrationCondition(): NadelHydrationWhenCondition? { - return null - } - private fun getHydrationCondition(hydration: UnderlyingServiceHydration): NadelHydrationWhenCondition? { if (hydration.conditionalHydration == null) { return null @@ -286,7 +282,7 @@ private class Factory( if (hydration.conditionalHydration.predicate.startsWith != null) { return NadelHydrationWhenCondition.StringResultStartsWith( fieldPath = NadelQueryPath(hydration.conditionalHydration.sourceField), - value = hydration.conditionalHydration.predicate.startsWith + prefix = hydration.conditionalHydration.predicate.startsWith ) } if (hydration.conditionalHydration.predicate.matches != null) { diff --git a/lib/src/main/java/graphql/nadel/engine/blueprint/hydration/NadelHydrationWhenCondition.kt b/lib/src/main/java/graphql/nadel/engine/blueprint/hydration/NadelHydrationWhenCondition.kt index 19fc68c2b..15e864891 100644 --- a/lib/src/main/java/graphql/nadel/engine/blueprint/hydration/NadelHydrationWhenCondition.kt +++ b/lib/src/main/java/graphql/nadel/engine/blueprint/hydration/NadelHydrationWhenCondition.kt @@ -25,7 +25,7 @@ sealed class NadelHydrationWhenCondition { data class StringResultStartsWith( val fieldPath: NadelQueryPath, - val value: String, + val prefix: String, ) : NadelHydrationWhenCondition() { override fun evaluate(resultId: String): Boolean { TODO("Not yet implemented")