Skip to content

Commit da0e821

Browse files
smyrickShane Myrick
andauthored
Call hooks for return type on properties (#1112)
Co-authored-by: Shane Myrick <[email protected]>
1 parent 77597c2 commit da0e821

File tree

6 files changed

+42
-10
lines changed

6 files changed

+42
-10
lines changed

examples/server/spring-server/src/main/kotlin/com/expediagroup/graphql/examples/server/spring/model/DataLoaderQueryModel.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,12 @@ import com.expediagroup.graphql.generator.annotations.GraphQLIgnore
2121

2222
data class Employee(
2323
val name: String,
24+
2425
@GraphQLIgnore
25-
val companyId: Int
26+
val companyId: Int,
27+
28+
@GraphQLDescription("A list of unique skills")
29+
val skills: Set<String> = emptySet()
2630
) {
2731
@GraphQLDescription("This value will be populated by a custom data fetcher using data loaders")
2832
lateinit var company: Company

examples/server/spring-server/src/main/kotlin/com/expediagroup/graphql/examples/server/spring/query/DataLoaderQuery.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ import java.util.concurrent.CompletableFuture
3333
@Component
3434
class DataLoaderQuery : Query {
3535
private val employees = listOf(
36-
Employee(name = "Mike", companyId = 1),
37-
Employee(name = "John", companyId = 1),
36+
Employee(name = "Mike", companyId = 1, skills = setOf("sales", "sales")),
37+
Employee(name = "John", companyId = 1, skills = setOf("management")),
3838
Employee(name = "Steve", companyId = 2)
3939
)
4040

examples/server/spring-server/src/main/kotlin/com/expediagroup/graphql/examples/server/spring/query/SimpleQuery.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,5 +84,6 @@ class SimpleQuery : Query {
8484
Selection.TWO -> "You chose the second one"
8585
}
8686

87-
fun setList(): Set<String> = setOf("one", "one", "two")
87+
@GraphQLDescription("Set exposed as a function")
88+
fun setList(): Set<Int> = setOf(1, 1, 2, 3)
8889
}

generator/graphql-kotlin-schema-generator/src/main/kotlin/com/expediagroup/graphql/generator/hooks/SchemaGeneratorHooks.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,14 @@ interface SchemaGeneratorHooks {
6868
fun willAddGraphQLTypeToSchema(type: KType, generatedType: GraphQLType): GraphQLType = generatedType
6969

7070
/**
71-
* Called before resolving a KType to the GraphQL type.
72-
* This allows for a custom resolver on how to extract wrapped values, like in a CompletableFuture.
71+
* Called before resolving a return type to the GraphQL type.
72+
* This allows for changes in the supported return types or unwrapping of specific classes.
7373
*/
7474
fun willResolveMonad(type: KType): KType = type
7575

7676
/**
77-
* Called before resolving a KType to the input GraphQL type.
78-
* This allows resolvers for custom deserialization logic of wrapped input values, like in an Optional.
77+
* Called before resolving an input type to the input GraphQL type.
78+
* This allows for changes in the supported input values and unwrapping of custom types, like in an Optional.
7979
*/
8080
fun willResolveInputMonad(type: KType): KType = type
8181

generator/graphql-kotlin-schema-generator/src/main/kotlin/com/expediagroup/graphql/generator/internal/types/generateProperty.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ import kotlin.reflect.KClass
3131
import kotlin.reflect.KProperty
3232

3333
internal fun generateProperty(generator: SchemaGenerator, prop: KProperty<*>, parentClass: KClass<*>): GraphQLFieldDefinition {
34-
val propertyType = generateGraphQLType(generator, type = prop.returnType)
34+
val typeFromHooks = generator.config.hooks.willResolveMonad(prop.returnType)
35+
val propertyType = generateGraphQLType(generator, type = typeFromHooks)
3536
.safeCast<GraphQLOutputType>()
3637

3738
val propertyName = prop.getPropertyName(parentClass)

generator/graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/generator/internal/types/GeneratePropertyTest.kt

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import com.expediagroup.graphql.generator.directives.KotlinDirectiveWiringFactor
2525
import com.expediagroup.graphql.generator.directives.KotlinSchemaDirectiveWiring
2626
import com.expediagroup.graphql.generator.execution.KotlinDataFetcherFactoryProvider
2727
import com.expediagroup.graphql.generator.execution.PropertyDataFetcher
28+
import com.expediagroup.graphql.generator.extensions.deepName
2829
import com.expediagroup.graphql.generator.hooks.SchemaGeneratorHooks
2930
import com.expediagroup.graphql.generator.internal.extensions.getSimpleName
3031
import com.expediagroup.graphql.generator.scalars.ID
@@ -41,6 +42,8 @@ import io.mockk.every
4142
import io.mockk.mockk
4243
import io.mockk.spyk
4344
import org.junit.jupiter.api.Test
45+
import kotlin.reflect.KType
46+
import kotlin.reflect.full.createType
4447
import kotlin.test.assertEquals
4548
import kotlin.test.assertFalse
4649
import kotlin.test.assertNotNull
@@ -53,7 +56,7 @@ class GeneratePropertyTest : TypeTestHelper() {
5356
@GraphQLDirective(locations = [Introspection.DirectiveLocation.FIELD_DEFINITION])
5457
internal annotation class PropertyDirective(val arg: String)
5558

56-
private class ClassWithProperties {
59+
class ClassWithProperties {
5760
@GraphQLDescription("It's not a lie")
5861
@PropertyDirective("trust me")
5962
val cake: String = "chocolate"
@@ -68,6 +71,8 @@ class GeneratePropertyTest : TypeTestHelper() {
6871

6972
@GraphQLName("pie")
7073
val renameMe: String = "apple"
74+
75+
val setList: Set<Int> = setOf(1, 1, 2, 3)
7176
}
7277

7378
private data class DataClassWithProperties(
@@ -227,4 +232,25 @@ class GeneratePropertyTest : TypeTestHelper() {
227232
assertEquals(expected = mockDataFetcher, actual = targetDataFetcher)
228233
localGenerator.close()
229234
}
235+
236+
@Test
237+
fun `hooks are called on properties`() {
238+
val hooks: SchemaGeneratorHooks = object : SchemaGeneratorHooks {
239+
override fun willResolveMonad(type: KType): KType = when (type.classifier) {
240+
Set::class -> List::class.createType(type.arguments)
241+
else -> type
242+
}
243+
}
244+
245+
val localConfig = SchemaGeneratorConfig(
246+
supportedPackages = emptyList(),
247+
hooks = hooks
248+
)
249+
val localGenerator = SchemaGenerator(localConfig)
250+
251+
val prop = ClassWithProperties::setList
252+
val result = generateProperty(localGenerator, prop, ClassWithProperties::class)
253+
254+
assertEquals("[Int!]!", result.type.deepName)
255+
}
230256
}

0 commit comments

Comments
 (0)