ExpediaGroup / graphql-kotlin

Libraries for running GraphQL in Kotlin

Home Page:https://opensource.expediagroup.com/graphql-kotlin/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

feat: allow classes corresponding to SDL to be decoupled from implementation

danadajian opened this issue · comments

Is your feature request related to a problem? Please describe.

I want to leverage abstract classes to define interfaces corresponding to schema types, and have separate resolver classes inherit from those abstract classes. This provides a type contract that I can enforce separately from my resolvers.

For example, if my desired schema is:

type Query {
  myQuery(): MyType
}

type MyType {
  myField(myArg: String!): String!
}

Currently I need to couple my Kotlin schema classes with my implementation, like so:

class MyQuery : Query {
  fun myQuery(): MyType = MyType()
}

class MyType {
  fun myField(myArg: String): String = "resolve me"
}

But I instead want to leverage an abstract Kotlin class that corresponds to the schema:

class MyQuery : Query {
  fun myQuery(): MyType = MyTypeResolver()
}

abstract class MyType {
  abstract fun myField(myArg: String): String
}

class MyTypeResolver : MyType() {
  override fun myField(myArg: String) = "resolve me"
}

I would include the abstract class MyType in scope for SDL generation, and I would exclude MyTypeResolver from SDL generation, such that the abstract class explicitly defines the resulting SDL. As a result, my Kotlin that corresponds to SDL can be decoupled from my implementation.

However, when I attempt to do this, I get the following error at runtime from graphql-java when executing a query:
Abstract type "MyType" must resolve to an Object type at runtime for field "MyType.myfield". Could not determine the exact type of "MyType"

Describe the solution you'd like
I would like it to be possible to define schema-specific interfaces in Kotlin in a way that is decoupled from my implementation. If the blocker here exists within graphql-java, I wonder if there is a way that graphql-kotlin can help us work around it. Maybe we can add support for a particular directive? 🤷