aPureBase / KGraphQL

Pure Kotlin GraphQL implementation
https://kgraphql.io
MIT License
301 stars 58 forks source link

Confusion with a list of union type #109

Closed Leopard2A5 closed 4 years ago

Leopard2A5 commented 4 years ago
import com.apurebase.kgraphql.KGraphQL
import kotlinx.coroutines.runBlocking
import org.junit.jupiter.api.Test

class InterfaceUnionTest {
    data class Wrapper(
        val items: List<QualificationItem>
    )

    sealed class QualificationItem {
        data class Qual1(
            val id: String
        ) : QualificationItem()
    }

    @Test
    fun test() {
        val schema = KGraphQL.schema {
            unionType<QualificationItem>()

            query("foo") {
                resolver { ->
                    Wrapper(listOf(QualificationItem.Qual1("12345")))
                }
            }
        }

        val foo = runBlocking {
            schema.execute("""
                query IntrospectionQuery {
                    __schema {
                        types {
                            kind
                            name
                        }
                    }
                }
            """)
        }
        println(foo)
    }
}

This fails with

An Object type must define one or more fields. Found none on type QualificationItem
com.apurebase.kgraphql.schema.SchemaException: An Object type must define one or more fields. Found none on type QualificationItem

The error disappears when you change the content of wrapper from a List to just QualificationItem.

Can't reproduce it, but i thought I'd seen QualificationItem show up as a type twice, once as an interface, once as a union.

Leopard2A5 commented 4 years ago

If i change the definition of QualificationItem to

sealed class QualificationItem(val dummy: String = "dummy") {
    data class Qual1(
        val id: String
    ) : QualificationItem()
}

then there's no error, however the introspection query returns (some types omitted)

{
    "data": {
        "__schema": {
            "types": [
                {
                    "kind": "INTERFACE",
                    "name": "QualificationItem"
                },
                {
                    "kind": "UNION",
                    "name": "QualificationItem"
                }
            ]
        }
    }
}

QualificationItem is defined once as an interface and once as a union. I suspect that the interface definition comes from the type's usage in Wrapper and the union def comes from the explicit unionType call.

Leopard2A5 commented 4 years ago

@jeggy what do you think?

jeggy commented 4 years ago

Thanks for these issues! These are exactly the kind of testing we need more of 😃

Leopard2A5 commented 4 years ago

Glad I could help, I really like the library 👍 Keep up the good work!

Leopard2A5 commented 4 years ago

Hope we can get a 0.15.3 soonish? This issue has been blocking me :)

jeggy commented 4 years ago

Yes, this will be available within 0.15.3 after this pipeline finishes 👍