Skip to content

Commit ab8deff

Browse files
gummybugviaductbot
authored andcommitted
Add NodeReference
Github-Change-Id: 945344 GitOrigin-RevId: 35e911745625143e506b1e45cd5b69bf456d96e7
1 parent 956bcad commit ab8deff

File tree

45 files changed

+337
-307
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+337
-307
lines changed

docs/content/docs/contributors/architecture/_index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ The `Viaduct` interface lives in the service domain and is the entry from the ap
5858

5959
To invoke the application-layer resolver code, the tenant-API implementation first needs to create an instance of the `ResolverBase` subclass containing the resolver function. This occurs by using an instance of `TenantCodeInjector` (an SPI) provisioned by Service Engineers when the configure Viaduct.
6060

61-
Once this chain of SPI enters into tenant module code, that tenant module code in turn uses the tenant developer API’s API abstractions – such as `ExecutionContext` – to leverage functionality provided to by the framework. In this particular example, the resolver is creating a “node reference” by calling `ExecutionContext.nodeFor`. Under the covers, the tenant-API’s implementation uses an `EngineExecutionContext` object – `EngineExecutionContext.createNodeEngineObjectData` in particular – to create this node reference. In our hypothetical example, this node reference is what is then returned by the resolver function, and in turn the `ResolverExecutor`, back to the engine.
61+
Once this chain of SPI enters into tenant module code, that tenant module code in turn uses the tenant developer API’s API abstractions – such as `ExecutionContext` – to leverage functionality provided to by the framework. In this particular example, the resolver is creating a “node reference” by calling `ExecutionContext.nodeFor`. Under the covers, the tenant-API’s implementation uses an `EngineExecutionContext` object – `EngineExecutionContext.createNodeReference` in particular – to create this node reference. In our hypothetical example, this node reference is what is then returned by the resolver function, and in turn the `ResolverExecutor`, back to the engine.
6262

6363
### Source Code Structure
6464

engine/api/src/main/kotlin/viaduct/engine/api/EngineExecutionContext.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ interface EngineExecutionContext {
3535
selections: RawSelectionSet
3636
): EngineObjectData = rawSelectionsLoaderFactory.forMutation(resolverId).load(selections)
3737

38-
fun createNodeEngineObjectData(
38+
fun createNodeReference(
3939
id: String,
4040
graphQLObjectType: GraphQLObjectType,
41-
): NodeEngineObjectData
41+
): NodeReference
4242

4343
// TODO(https://app.asana.com/1/150975571430/project/1203659453427089/task/1210861903745772):
4444
// remove when everything has been shimmed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package viaduct.engine.api
2+
3+
import graphql.schema.GraphQLObjectType
4+
5+
/**
6+
* A representation of a GraphQL object type
7+
*/
8+
interface EngineObject {
9+
val graphQLObjectType: GraphQLObjectType
10+
}

engine/api/src/main/kotlin/viaduct/engine/api/EngineObjectData.kt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package viaduct.engine.api
22

3-
import graphql.schema.GraphQLObjectType
4-
53
/**
64
* An untyped representation of resolved GraphQL object values. These
75
* values can be nested. For list-typed fields, the Kotlin [List]
@@ -41,7 +39,7 @@ import graphql.schema.GraphQLObjectType
4139
* must _not_ assume that application code is correct and instead must
4240
* validate conformance.)
4341
*/
44-
interface EngineObjectData {
42+
interface EngineObjectData : EngineObject {
4543
/**
4644
* Fetch a value that was selected with the provided [selection]
4745
*
@@ -55,6 +53,4 @@ interface EngineObjectData {
5553
* reading unset selections.
5654
*/
5755
suspend fun fetchOrNull(selection: String): Any?
58-
59-
val graphQLObjectType: GraphQLObjectType
6056
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package viaduct.engine.api
2+
3+
/**
4+
* A reference to a node object. Unlike [EngineObjectData], This does not provide access to the
5+
* node's fields, only its ID.
6+
*/
7+
interface NodeReference : EngineObject {
8+
/** a serialized representation of a Node's GlobalID */
9+
val id: String
10+
}

engine/api/src/test/kotlin/viaduct/engine/api/mocks/MockTenantModuleBootstrapperDSLTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class MockTenantModuleBootstrapperDSLTest {
4949
val module = MockTenantModuleBootstrapper(SCHEMA_SDL) {
5050
field(coord) {
5151
valueFromContext { ctx ->
52-
ctx.createNodeEngineObjectData("123", schema.schema.getObjectType("Test"))
52+
ctx.createNodeReference("123", schema.schema.getObjectType("Test"))
5353
}
5454
}
5555
}

engine/runtime/src/main/kotlin/viaduct/engine/runtime/EngineExecutionContextImpl.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class EngineExecutionContextImpl(
7272
val dataFetchingEnvironment: DataFetchingEnvironment? = null,
7373
override val activeSchema: ViaductSchema = fullSchema,
7474
) : EngineExecutionContext {
75-
override fun createNodeEngineObjectData(
75+
override fun createNodeReference(
7676
id: String,
7777
graphQLObjectType: GraphQLObjectType
7878
) = NodeEngineObjectDataImpl(id, graphQLObjectType, dispatcherRegistry, dispatcherRegistry)

engine/runtime/src/main/kotlin/viaduct/engine/runtime/NodeEngineObjectDataImpl.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import kotlinx.coroutines.supervisorScope
77
import viaduct.engine.api.EngineExecutionContext
88
import viaduct.engine.api.EngineObjectData
99
import viaduct.engine.api.NodeEngineObjectData
10+
import viaduct.engine.api.NodeReference
1011
import viaduct.engine.api.NodeResolverDispatcherRegistry
1112
import viaduct.engine.api.RawSelectionSet
1213
import viaduct.engine.api.TypeCheckerDispatcherRegistry
@@ -16,7 +17,7 @@ class NodeEngineObjectDataImpl(
1617
override val graphQLObjectType: GraphQLObjectType,
1718
private val resolverRegistry: NodeResolverDispatcherRegistry,
1819
private val checkerRegistry: TypeCheckerDispatcherRegistry
19-
) : NodeEngineObjectData {
20+
) : NodeEngineObjectData, NodeReference {
2021
private lateinit var resolvedEngineObjectData: EngineObjectData
2122
private val resolving = CompletableDeferred<Unit>()
2223

engine/runtime/src/test/kotlin/viaduct/engine/runtime/AccessCheckExecutionTest.kt

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ class AccessCheckExecutionTest {
372372
MockTenantModuleBootstrapper(schema) {
373373
field("Query" to "baz") {
374374
resolver {
375-
fn { _, _, _, _, ctx -> ctx.createNodeEngineObjectData("1", bazType) }
375+
fn { _, _, _, _, ctx -> ctx.createNodeReference("1", bazType) }
376376
}
377377
checker {
378378
fn { _, _ -> throw RuntimeException("field checker failed") }
@@ -401,7 +401,7 @@ class AccessCheckExecutionTest {
401401
MockTenantModuleBootstrapper(schema) {
402402
field("Query" to "baz") {
403403
resolver {
404-
fn { _, _, _, _, ctx -> ctx.createNodeEngineObjectData("1", bazType) }
404+
fn { _, _, _, _, ctx -> ctx.createNodeReference("1", bazType) }
405405
}
406406
checker {
407407
fn { _, _ -> /* access granted */ }
@@ -430,7 +430,7 @@ class AccessCheckExecutionTest {
430430
MockTenantModuleBootstrapper(schema) {
431431
field("Query" to "baz") {
432432
resolver {
433-
fn { _, _, _, _, ctx -> ctx.createNodeEngineObjectData("1", bazType) }
433+
fn { _, _, _, _, ctx -> ctx.createNodeReference("1", bazType) }
434434
}
435435
checker {
436436
fn { _, _ -> /* access granted */ }
@@ -456,7 +456,7 @@ class AccessCheckExecutionTest {
456456
MockTenantModuleBootstrapper(schema) {
457457
field("Query" to "baz") {
458458
resolver {
459-
fn { _, _, _, _, ctx -> ctx.createNodeEngineObjectData("1", bazType) }
459+
fn { _, _, _, _, ctx -> ctx.createNodeReference("1", bazType) }
460460
}
461461
}
462462
type("Baz") {
@@ -482,7 +482,7 @@ class AccessCheckExecutionTest {
482482
MockTenantModuleBootstrapper(schema) {
483483
field("Query" to "nonNullBaz") {
484484
resolver {
485-
fn { _, _, _, _, ctx -> ctx.createNodeEngineObjectData("1", bazType) }
485+
fn { _, _, _, _, ctx -> ctx.createNodeReference("1", bazType) }
486486
}
487487
}
488488
type("Baz") {
@@ -508,7 +508,7 @@ class AccessCheckExecutionTest {
508508
MockTenantModuleBootstrapper(schema) {
509509
field("Query" to "node") {
510510
resolver {
511-
fn { _, _, _, _, ctx -> ctx.createNodeEngineObjectData("1", bazType) }
511+
fn { _, _, _, _, ctx -> ctx.createNodeReference("1", bazType) }
512512
}
513513
}
514514
type("Baz") {
@@ -535,7 +535,7 @@ class AccessCheckExecutionTest {
535535
MockTenantModuleBootstrapper(schema) {
536536
field("Query" to "node") {
537537
resolver {
538-
fn { _, _, _, _, ctx -> ctx.createNodeEngineObjectData("1", bazType) }
538+
fn { _, _, _, _, ctx -> ctx.createNodeReference("1", bazType) }
539539
}
540540
}
541541
type("Baz") {
@@ -560,7 +560,7 @@ class AccessCheckExecutionTest {
560560
MockTenantModuleBootstrapper(schema) {
561561
field("Query" to "baz") {
562562
resolver {
563-
fn { _, _, _, _, ctx -> ctx.createNodeEngineObjectData("1", bazType) }
563+
fn { _, _, _, _, ctx -> ctx.createNodeReference("1", bazType) }
564564
}
565565
}
566566
field("Baz" to "y") {
@@ -599,7 +599,7 @@ class AccessCheckExecutionTest {
599599
MockTenantModuleBootstrapper(schema) {
600600
field("Query" to "baz") {
601601
resolver {
602-
fn { _, _, _, _, ctx -> ctx.createNodeEngineObjectData("1", bazType) }
602+
fn { _, _, _, _, ctx -> ctx.createNodeReference("1", bazType) }
603603
}
604604
}
605605
field("Baz" to "y") {
@@ -641,9 +641,9 @@ class AccessCheckExecutionTest {
641641
resolver {
642642
fn { _, _, _, _, ctx ->
643643
listOf(
644-
ctx.createNodeEngineObjectData("1", bazType),
645-
ctx.createNodeEngineObjectData("2", bazType),
646-
ctx.createNodeEngineObjectData("3", bazType),
644+
ctx.createNodeReference("1", bazType),
645+
ctx.createNodeReference("2", bazType),
646+
ctx.createNodeReference("3", bazType),
647647
)
648648
}
649649
}
@@ -696,9 +696,9 @@ class AccessCheckExecutionTest {
696696
resolver {
697697
fn { _, _, _, _, ctx ->
698698
listOf(
699-
ctx.createNodeEngineObjectData("1", bazType),
700-
ctx.createNodeEngineObjectData("2", bazType),
701-
ctx.createNodeEngineObjectData("3", bazType),
699+
ctx.createNodeReference("1", bazType),
700+
ctx.createNodeReference("2", bazType),
701+
ctx.createNodeReference("3", bazType),
702702
)
703703
}
704704
}
@@ -748,9 +748,9 @@ class AccessCheckExecutionTest {
748748
resolver {
749749
fn { _, _, _, _, ctx ->
750750
listOf(
751-
ctx.createNodeEngineObjectData("1", bazType),
752-
ctx.createNodeEngineObjectData("2", barType),
753-
ctx.createNodeEngineObjectData("3", barType),
751+
ctx.createNodeReference("1", bazType),
752+
ctx.createNodeReference("2", barType),
753+
ctx.createNodeReference("3", barType),
754754
)
755755
}
756756
}

engine/runtime/src/test/kotlin/viaduct/engine/runtime/BatchNodeResolverTest.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class BatchNodeResolverTest {
3434
field("Query" to "baz") {
3535
resolver {
3636
fn { _, _, _, _, ctx ->
37-
ctx.createNodeEngineObjectData("1", schema.schema.getObjectType("Baz"))
37+
ctx.createNodeReference("1", schema.schema.getObjectType("Baz"))
3838
}
3939
}
4040
}
@@ -64,7 +64,7 @@ class BatchNodeResolverTest {
6464
resolver {
6565
fn { _, _, _, _, ctx ->
6666
(1..3).map { i ->
67-
ctx.createNodeEngineObjectData(i.toString(), schema.schema.getObjectType("Baz"))
67+
ctx.createNodeReference(i.toString(), schema.schema.getObjectType("Baz"))
6868
}
6969
}
7070
}
@@ -98,7 +98,7 @@ class BatchNodeResolverTest {
9898
resolver {
9999
fn { _, _, _, _, ctx ->
100100
(1..3).map { i ->
101-
ctx.createNodeEngineObjectData(i.toString(), schema.schema.getObjectType("Baz"))
101+
ctx.createNodeReference(i.toString(), schema.schema.getObjectType("Baz"))
102102
}
103103
}
104104
}
@@ -127,7 +127,7 @@ class BatchNodeResolverTest {
127127
resolver {
128128
fn { _, _, _, _, ctx ->
129129
(1..3).map { i ->
130-
ctx.createNodeEngineObjectData(i.toString(), schema.schema.getObjectType("Baz"))
130+
ctx.createNodeReference(i.toString(), schema.schema.getObjectType("Baz"))
131131
}
132132
}
133133
}
@@ -166,7 +166,7 @@ class BatchNodeResolverTest {
166166
field("Query" to "baz") {
167167
resolver {
168168
fn { _, _, _, _, ctx ->
169-
ctx.createNodeEngineObjectData("1", schema.schema.getObjectType("Baz"))
169+
ctx.createNodeReference("1", schema.schema.getObjectType("Baz"))
170170
}
171171
}
172172
}
@@ -176,7 +176,7 @@ class BatchNodeResolverTest {
176176
fn { _, objectValue, _, _, ctx ->
177177
// Make this wait for the first Baz node resolver to be dispatched
178178
objectValue.fetch("x")
179-
ctx.createNodeEngineObjectData("1", schema.schema.getObjectType("Baz"))
179+
ctx.createNodeReference("1", schema.schema.getObjectType("Baz"))
180180
}
181181
}
182182
}
@@ -209,7 +209,7 @@ class BatchNodeResolverTest {
209209
field("Query" to "baz") {
210210
resolver {
211211
fn { _, _, _, _, ctx ->
212-
ctx.createNodeEngineObjectData("1", schema.schema.getObjectType("Baz"))
212+
ctx.createNodeReference("1", schema.schema.getObjectType("Baz"))
213213
}
214214
}
215215
}
@@ -219,7 +219,7 @@ class BatchNodeResolverTest {
219219
fn { _, objectValue, _, _, ctx ->
220220
// Make this wait for the first Baz node resolver to be dispatched
221221
objectValue.fetch("x")
222-
ctx.createNodeEngineObjectData("1", schema.schema.getObjectType("Baz"))
222+
ctx.createNodeReference("1", schema.schema.getObjectType("Baz"))
223223
}
224224
}
225225
}

0 commit comments

Comments
 (0)