Skip to content

Commit

Permalink
Support single source ID in new batch hydrator (#473)
Browse files Browse the repository at this point in the history
  • Loading branch information
gnawf authored Dec 6, 2023
1 parent 79c58b5 commit 1663538
Show file tree
Hide file tree
Showing 4 changed files with 309 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -231,15 +231,16 @@ internal class NadelNewBatchHydrator(
fieldName = state.hydratedField.name,
)

val fieldSource = instructions
.first()
.actorInputValueDefs
.asSequence()
.map {
it.valueSource
}
.singleOfType<ValueSource.FieldResultValue>()

return if (executionBlueprint.engineSchema.getField(coords)!!.type.unwrapNonNull().isList) {
val fieldSource = instructions
.first()
.actorInputValueDefs
.asSequence()
.map {
it.valueSource
}
.singleOfType<ValueSource.FieldResultValue>()

// todo: move this to validation
instructions
Expand All @@ -261,7 +262,18 @@ internal class NadelNewBatchHydrator(
sourceId to instruction
}
} else {
throw UnsupportedOperationException("todo")
// todo: determine what to do here in the longer term, this hook should probably be replaced
val instruction = state.executionContext.hooks.getHydrationInstruction(
instructions = instructions,
parentNode = parentNode,
aliasHelper = state.aliasHelper,
userContext = state.executionContext.userContext,
)!!

extractValues(parentNode, fieldSource, state.aliasHelper)
.map { sourceId ->
sourceId to instruction
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package graphql.nadel.tests.hooks

import graphql.nadel.Nadel
import graphql.nadel.NadelExecutionHints
import graphql.nadel.engine.blueprint.NadelGenericHydrationInstruction
import graphql.nadel.engine.blueprint.hydration.NadelHydrationActorInputDef.ValueSource
import graphql.nadel.engine.transform.artificial.NadelAliasHelper
import graphql.nadel.engine.transform.result.json.JsonNode
import graphql.nadel.engine.transform.result.json.JsonNodeExtractor
import graphql.nadel.engine.util.singleOfType
import graphql.nadel.hooks.NadelExecutionHooks
import graphql.nadel.tests.EngineTestHook
import graphql.nadel.tests.UseHook

@UseHook
class `new-batching-single-source-id` : EngineTestHook {
override fun makeExecutionHints(builder: NadelExecutionHints.Builder): NadelExecutionHints.Builder {
return super.makeExecutionHints(builder)
.newBatchHydrationGrouping { true }
}

override fun makeNadel(builder: Nadel.Builder): Nadel.Builder {
return super.makeNadel(builder)
.executionHooks(
object : NadelExecutionHooks {
override fun <T : NadelGenericHydrationInstruction> getHydrationInstruction(
instructions: List<T>,
parentNode: JsonNode,
aliasHelper: NadelAliasHelper,
userContext: Any?,
): T? {
return instructions
.single { instruction ->
val fieldSource = instruction.actorInputValueDefs
.asSequence()
.map {
it.valueSource
}
.singleOfType<ValueSource.FieldResultValue>()

val sourceNodes = JsonNodeExtractor.getNodesAt(
parentNode,
aliasHelper.getQueryPath(fieldSource.queryPathToField)
)
val sourceIdType = (sourceNodes.single().value as String).substringBefore("/")

instruction.actorService.name.startsWith(sourceIdType)
}
}
},
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
name: "new batching single source id"
enabled: true
overallSchema:
# language=GraphQL
activity: |
type Query {
activity: [Activity]
}
union ActivityContent = Issue | Comment
type Activity {
id: ID!
contentId: ID!
content: ActivityContent
@hydrated(
service: "comments"
field: "commentsByIds"
arguments: [
{name: "ids" value: "$source.contentId"}
]
)
@hydrated(
service: "issues"
field: "issuesByIds"
arguments: [
{name: "ids" value: "$source.contentId"}
]
)
}
# language=GraphQL
issues: |
type Query {
issuesByIds(ids: [ID!]!): [Issue!]
}
type Issue {
id: ID!
title: String
}
# language=GraphQL
comments: |
type Query {
commentsByIds(ids: [ID!]!): [Comment!]
}
type Comment {
id: ID!
content: String
}
underlyingSchema:
# language=GraphQL
activity: |
type Query {
activity: [Activity]
}
type Activity {
id: ID!
contentId: ID!
}
# language=GraphQL
issues: |
type Query {
issuesByIds(ids: [ID!]!): [Issue!]
}
type Issue {
id: ID!
title: String
}
# language=GraphQL
comments: |
type Query {
commentsByIds(ids: [ID!]!): [Comment!]
}
type Comment {
id: ID!
content: String
}
# language=GraphQL
query: |
{
activity {
content {
__typename
... on Issue {
id
title
}
... on Comment {
id
content
}
}
}
}
variables: { }
serviceCalls:
- serviceName: "activity"
request:
# language=GraphQL
query: |
{
activity {
__typename__batch_hydration__content: __typename
batch_hydration__content__contentId: contentId
batch_hydration__content__contentId: contentId
}
}
variables: { }
# language=JSON
response: |-
{
"data": {
"activity": [
{
"__typename__batch_hydration__content": "Activity",
"batch_hydration__content__contentId": "issue/4000"
},
{
"__typename__batch_hydration__content": "Activity",
"batch_hydration__content__contentId": "issue/8080"
},
{
"__typename__batch_hydration__content": "Activity",
"batch_hydration__content__contentId": "issue/7496"
},
{
"__typename__batch_hydration__content": "Activity",
"batch_hydration__content__contentId": "comment/1234"
}
]
},
"extensions": {}
}
- serviceName: "issues"
request:
# language=GraphQL
query: |
{
issuesByIds(ids: ["issue/4000", "issue/8080", "issue/7496"]) {
__typename
id
batch_hydration__content__id: id
title
}
}
variables: { }
# language=JSON
response: |-
{
"data": {
"issuesByIds": [
{
"__typename": "Issue",
"id": "issue/4000",
"batch_hydration__content__id": "issue/4000",
"title": "Four Thousand"
},
{
"__typename": "Issue",
"id": "issue/8080",
"batch_hydration__content__id": "issue/8080",
"title": "Eighty Eighty"
},
{
"__typename": "Issue",
"id": "issue/7496",
"batch_hydration__content__id": "issue/7496",
"title": "Seven Four Nine Six"
}
]
},
"extensions": {}
}
- serviceName: "comments"
request:
# language=GraphQL
query: |
{
commentsByIds(ids: ["comment/1234"]) {
__typename
content
id
batch_hydration__content__id: id
}
}
variables: { }
# language=JSON
response: |-
{
"data": {
"commentsByIds": [
{
"__typename": "Comment",
"id": "comment/1234",
"batch_hydration__content__id": "comment/1234",
"content": "One Two Three Four"
}
]
},
"extensions": {}
}
# language=JSON
response: |-
{
"data": {
"activity": [
{
"content": {
"__typename": "Issue",
"id": "issue/4000",
"title": "Four Thousand"
}
},
{
"content": {
"__typename": "Issue",
"id": "issue/8080",
"title": "Eighty Eighty"
}
},
{
"content": {
"__typename": "Issue",
"id": "issue/7496",
"title": "Seven Four Nine Six"
}
},
{
"content": {
"__typename": "Comment",
"id": "comment/1234",
"content": "One Two Three Four"
}
}
]
},
"errors": []
}

0 comments on commit 1663538

Please sign in to comment.