https://kotlinlang.org logo
#graphql-kotlin
Title
# graphql-kotlin
d

Dariusz Kuc

01/09/2020, 1:30 PM
hello, i personally would just do a suspendable function, since our functions effectively become the data fetcher in
graphql-java
world there is really no need for the data loader, e.g.
Copy code
class Employee(val name: String, private val companyId: Int) {
  suspend fun company() = myCompanyService.load(companyId)
}
there are number of ways of how to expose the
myCompanyService
in the above
it really depends how deep/complex autowiring is
Top level queries/objects can easily autowire stuff
Once you go deeper then you still can use it but you got to use some bean factory to create those objects
See our examples under graphql kotlin repo
Instead of autowiring sometimes calling the constructor might be easier
r

Robert

02/08/2020, 7:46 PM
I don’t know your code but I don’t think every employee should have a dependency on companyService.
d

Darren

02/11/2020, 4:55 PM
Right, Robert that’s the awkwardness I’m trying to avoid - an output type shouldn’t have a service dependency. We’ve been using the lateinit approach with data loaders, but there’s a level of indirection there that would be nice to avoid
r

Robert

02/11/2020, 5:02 PM
Would some kind of AOP work?
Or Kotlin delegates?
d

Dariusz Kuc

02/11/2020, 5:58 PM
an output type shouldn’t have a service dependency
why not? your output classes don't have to be simple data classes/POJOs and if you were to use them as such you will be severely limiting yourself (e.g. functions will only be invoked if your query requests for it vs fields get calculated always)
d

Darren

02/11/2020, 6:51 PM
Yea, so my preference would be to use functions to define expensive fields, but it complicates the creation of those output types - on one hand we want them to be data classes / POJOs because some service will be building, but in order to resolve a function a separate service would need to be injected into the out put type (e.g. employee service is building employee objects, but shouldn’t need to inject the company service into the employee objects)
d

Dariusz Kuc

02/11/2020, 6:55 PM
well another alternative is to look into adding support for extension functions (https://github.com/ExpediaGroup/graphql-kotlin/issues/383)
while we don't support it out of the box it is possible to add support through the hooks
spring AOP doesn’t really work with reactive stuff
well something like before/after might be ok, around aspects might have trouble
… or not -> with coroutines you can enter the same function multiple times due to the callbacks on continuation….
r

Robert

04/29/2020, 7:38 AM
Oh good hint regarding AOP. Will try to leverage Kotlin Delegation for this ... let's see
Back to my favorite topic 😂 my current workaround is a nullable property, which is of course reflected in the schema and not optimal. The field is populated only when requested. I think this could be better if the schema object is an interface, where the conditional property is a function. The DataLoader just creates an instance of it if requested. And some kind of dummy value for the nested field if not requested -> client will never see this.
d

Darren

05/07/2020, 9:54 PM
The approach we ended up using was an interface with a default function annotated with a custom annotation
@Fetchable
. A custom data fetcher factory looks for properties with that custom annotation. This also lets us define the contract for how we resolve a related object (e.g. a product has a category, but must expose the category id for the data fetcher to resolve the related category)
🚀 1
4 Views