Skip to content

Commit 59396a0

Browse files
gscheibelbrennantaylor
authored andcommitted
Prevent object type for recreating when they mix union and interfaces (#42)
1 parent e5394f0 commit 59396a0

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

src/main/kotlin/com/expedia/graphql/schema/generator/SchemaGenerator.kt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -309,9 +309,14 @@ internal class SchemaGenerator(
309309
val interfaceType = builder.build()
310310

311311
val implementations = getSubTypesOf(kClass)
312-
implementations.forEach {
313-
additionTypes.add(objectType(it.kotlin, interfaceType))
314-
}
312+
implementations
313+
.filterNot { it.kotlin.isAbstract }
314+
.forEach {
315+
val objectType = objectType(it.kotlin, interfaceType)
316+
val key = TypesCacheKey(it.kotlin.createType(), false)
317+
additionTypes.add(objectType)
318+
cache.put(key, KGraphQLType(it.kotlin, objectType))
319+
}
315320

316321
return interfaceType
317322
}
@@ -325,8 +330,12 @@ internal class SchemaGenerator(
325330

326331
val implementations = getSubTypesOf(kClass)
327332
implementations
333+
.filterNot { it.kotlin.isAbstract }
328334
.forEach {
335+
val objectType = objectType(it.kotlin)
336+
val key = TypesCacheKey(it.kotlin.createType(), false)
329337
builder.possibleType(objectType(it.kotlin) as GraphQLObjectType)
338+
cache.put(key, KGraphQLType(it.kotlin, objectType))
330339
}
331340

332341
return builder.build()

src/test/kotlin/com/expedia/graphql/schema/generator/PolymorphicTests.kt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import com.expedia.graphql.TopLevelObjectDef
44
import com.expedia.graphql.schema.exceptions.InvalidInputFieldTypeException
55
import com.expedia.graphql.schema.testSchemaConfig
66
import com.expedia.graphql.toSchema
7+
import graphql.schema.GraphQLObjectType
78
import graphql.schema.GraphQLUnionType
89
import org.junit.jupiter.api.Assertions.assertThrows
910
import org.junit.jupiter.api.Test
@@ -54,6 +55,25 @@ class PolymorphicTests {
5455
toSchema(listOf(TopLevelObjectDef(QueryWithUnAuthorizedUnionArgument())), config = testSchemaConfig)
5556
}
5657
}
58+
59+
@Test
60+
fun `Object types implementing union and interfaces are only created once`() {
61+
val schema = toSchema(listOf(TopLevelObjectDef(QueryWithInterfaceAnUnion())), config = testSchemaConfig)
62+
63+
val carType = schema.getType("Car") as? GraphQLObjectType
64+
assertNotNull(carType)
65+
66+
carType?.let {
67+
assertNotNull(it.getFieldDefinition("model"))
68+
assertNotNull(it.getFieldDefinition("color"))
69+
}
70+
71+
val productType = schema.getType("Product") as? GraphQLUnionType
72+
assertNotNull(productType)
73+
productType?.let {
74+
assertTrue { it.types.contains(carType) }
75+
}
76+
}
5777
}
5878

5979
class QueryWithInterface {
@@ -94,3 +114,15 @@ data class LeftHand(
94114
data class RightHand(
95115
val property: Int
96116
) : BodyPart
117+
118+
class QueryWithInterfaceAnUnion {
119+
fun product(): Product = Car("DB9", "black")
120+
}
121+
122+
interface Vehicle {
123+
val color: String
124+
}
125+
126+
interface Product
127+
128+
data class Car(val model: String, override val color: String) : Vehicle, Product

0 commit comments

Comments
 (0)