Skip to content

Commit b1914cb

Browse files
Added integration tests to demonstrate behaviour functioning
1 parent 5ea22db commit b1914cb

2 files changed

Lines changed: 199 additions & 0 deletions

File tree

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package graphql.nadel.tests.next.fixtures.batching
2+
3+
import graphql.nadel.Nadel
4+
import graphql.nadel.NadelExecutionHints
5+
import graphql.nadel.engine.NadelExecutionContext
6+
import graphql.nadel.hooks.NadelExecutionHooks
7+
import graphql.nadel.tests.next.NadelIntegrationTest
8+
import graphql.normalized.ExecutableNormalizedField
9+
10+
/**
11+
* Root fields owned by the same service but routed to different shards must NOT be batched together.
12+
*
13+
* Here [getShardingTarget] returns the field's `cloudId` argument as the (opaque) shard key, so:
14+
* - `a` + `b` (cloudId "site-1") share a shard and batch into a single call
15+
* - `c` (cloudId "site-2") is a different shard and is sent separately
16+
*
17+
* The snapshot therefore records TWO calls to the "issues" service: one for site-1 (a + b) and one
18+
* for site-2 (c).
19+
*/
20+
class BatchRootFieldsByShardTest : NadelIntegrationTest(
21+
query = """
22+
query {
23+
a: issueById(cloudId: "site-1") { id }
24+
b: issueById(cloudId: "site-1") { id }
25+
c: issueById(cloudId: "site-2") { id }
26+
}
27+
""".trimIndent(),
28+
services = listOf(
29+
Service(
30+
name = "issues",
31+
overallSchema = """
32+
type Query {
33+
issueById(cloudId: String!): Issue
34+
}
35+
type Issue {
36+
id: ID
37+
}
38+
""".trimIndent(),
39+
runtimeWiring = { wiring ->
40+
wiring
41+
.type("Query") { type ->
42+
type
43+
.dataFetcher("issueById") { env ->
44+
mapOf("id" to env.getArgument<String>("cloudId"))
45+
}
46+
}
47+
},
48+
),
49+
),
50+
) {
51+
override fun makeExecutionHints(): NadelExecutionHints.Builder {
52+
return super.makeExecutionHints()
53+
.batchRootFields { true }
54+
}
55+
56+
override fun makeNadel(): Nadel.Builder {
57+
return super.makeNadel()
58+
.executionHooks(
59+
object : NadelExecutionHooks {
60+
override fun getShardingTarget(
61+
executionContext: NadelExecutionContext,
62+
service: graphql.nadel.Service,
63+
field: ExecutableNormalizedField,
64+
): Any? {
65+
return field.resolvedArguments["cloudId"]
66+
}
67+
},
68+
)
69+
}
70+
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// @formatter:off
2+
package graphql.nadel.tests.next.fixtures.batching
3+
4+
import graphql.nadel.tests.next.ExpectedNadelResult
5+
import graphql.nadel.tests.next.ExpectedServiceCall
6+
import graphql.nadel.tests.next.TestSnapshot
7+
import graphql.nadel.tests.next.listOfJsonStrings
8+
import kotlin.Suppress
9+
import kotlin.collections.List
10+
import kotlin.collections.listOf
11+
12+
private suspend fun main() {
13+
graphql.nadel.tests.next.update<BatchRootFieldsByShardTest>()
14+
}
15+
16+
/**
17+
* This class is generated. Do NOT modify.
18+
*
19+
* Refer to [graphql.nadel.tests.next.UpdateTestSnapshots]
20+
*/
21+
@Suppress("unused")
22+
public class BatchRootFieldsByShardTestSnapshot : TestSnapshot() {
23+
/**
24+
* Query
25+
*
26+
* ```graphql
27+
* query {
28+
* a: issueById(cloudId: "site-1") { id }
29+
* b: issueById(cloudId: "site-1") { id }
30+
* c: issueById(cloudId: "site-2") { id }
31+
* }
32+
* ```
33+
*
34+
* Variables
35+
*
36+
* ```json
37+
* {}
38+
* ```
39+
*/
40+
override val calls: List<ExpectedServiceCall> = listOf(
41+
ExpectedServiceCall(
42+
service = "issues",
43+
query = """
44+
| {
45+
| a: issueById(cloudId: "site-1") {
46+
| id
47+
| }
48+
| b: issueById(cloudId: "site-1") {
49+
| id
50+
| }
51+
| }
52+
""".trimMargin(),
53+
variables = "{}",
54+
result = """
55+
| {
56+
| "data": {
57+
| "a": {
58+
| "id": "site-1"
59+
| },
60+
| "b": {
61+
| "id": "site-1"
62+
| }
63+
| }
64+
| }
65+
""".trimMargin(),
66+
delayedResults = listOfJsonStrings(
67+
),
68+
),
69+
ExpectedServiceCall(
70+
service = "issues",
71+
query = """
72+
| {
73+
| c: issueById(cloudId: "site-2") {
74+
| id
75+
| }
76+
| }
77+
""".trimMargin(),
78+
variables = "{}",
79+
result = """
80+
| {
81+
| "data": {
82+
| "c": {
83+
| "id": "site-2"
84+
| }
85+
| }
86+
| }
87+
""".trimMargin(),
88+
delayedResults = listOfJsonStrings(
89+
),
90+
),
91+
)
92+
93+
/**
94+
* ```json
95+
* {
96+
* "data": {
97+
* "a": {
98+
* "id": "site-1"
99+
* },
100+
* "b": {
101+
* "id": "site-1"
102+
* },
103+
* "c": {
104+
* "id": "site-2"
105+
* }
106+
* }
107+
* }
108+
* ```
109+
*/
110+
override val result: ExpectedNadelResult = ExpectedNadelResult(
111+
result = """
112+
| {
113+
| "data": {
114+
| "a": {
115+
| "id": "site-1"
116+
| },
117+
| "b": {
118+
| "id": "site-1"
119+
| },
120+
| "c": {
121+
| "id": "site-2"
122+
| }
123+
| }
124+
| }
125+
""".trimMargin(),
126+
delayedResults = listOfJsonStrings(
127+
),
128+
)
129+
}

0 commit comments

Comments
 (0)